Home > Back-end >  Loop failing to create a fieldset of checkboxes
Loop failing to create a fieldset of checkboxes

Time:07-08

As part of a web app I'm building in Google Apps Script, I'm trying to create a checkbox field that shows one checkbox for each learner/student, arranged in rows of 3. The learner data is being taken from a spreadsheet (this bit is working fine).

I want the checkboxes to look like this:

image of 6 checkboxes, in 2 rows of 3

1

The problem I am having is that my code is inserting the closing fieldset tag in the wrong place (too early) and so the checkboxes don't look right (I'm using the jquery mobile 1.4.5 framework).

I've been staring at the code and tinkering with it for hours, I'm hoping it's something simple I just can't see and hoping someone can help me fix it.

The code I am using is basically a nested loop - the outer loop should create the fieldset tags for each row, and the inner loop should create each checkbox. My code is as follows:

  1. First the container div

<div id="learners">Loading...</div>

  1. The javascript to grab the data and replace the container div above with it...

// The code in this function runs when the page is loaded.
  $(function() {
    google.script.run.withSuccessHandler(showLearners)
        .getLearnerData();
  });

  function showLearners(learners) {
    var learnerCheckboxes = $('#learners');
    learnerCheckboxes.empty();
    var cols=['a','b','c'];

    for (var i = 0; i < learners.length; i  ) {
      learnerCheckboxes.append("<fieldset class=\"ui-grid-b\">");

      for (var j = 0; j < 3; j  ) {
        learnerCheckboxes.append(
          "<div class=\"ui-block-"   cols[j]   "\">"  
            "<input type=\"checkbox\" name=\"learner\" id=\"learner"   i   "\" data-mini=\"true\">"  
            "<label for=\"learner"   i   "\">"   learners[i][0]   "</label>"  
          "</div>"
        );
        i  
      }

      learnerCheckboxes.append("</fieldset>");
    }
  }

The problem is, when the code runs, the closing </fieldset> is inserted too early... here's the output from this code:

<div id="learners">
  <fieldset >
  </fieldset><!-- THIS IS THE PROBLEM - IT SHOULD BE AT THE BOTTOM OF THIS GROUP?-->
  <div >
    <input type="checkbox" name="learner" id="learner0" data-mini="true">
    <label for="learner0">David</label>
  </div>
  <div >
    <input type="checkbox" name="learner" id="learner1" data-mini="true">
    <label for="learner1">Dominic</label>
  </div>
  <div >
    <input type="checkbox" name="learner" id="learner2" data-mini="true">
    <label for="learner2">Eliza</label>
  </div>
  
  <fieldset >
  </fieldset><!-- THIS SHOULD BE AT THE BOTTOM OF THIS GROUP-->
  <div >
    <input type="checkbox" name="learner" id="learner4" data-mini="true">
   <label for="learner4">Francois</label>
  </div>
  <div >
    <input type="checkbox" name="learner" id="learner5" data-mini="true">
    <label for="learner5">James</label></div>
  <div >
    <input type="checkbox" name="learner" id="learner6" data-mini="true">
    <label for="learner6">Louise</label>
  </div>
</div>

CodePudding user response:

It took a lot of trial and error because I don't use jquery. I do it the old fashion way. But I finally got it to work. You can play with the CSS to get it to look like you want.

HTML_Test.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  </head>
  <body>
    <div id="learners">Loading...</div>
    <script>
      (function() {
        google.script.run.withSuccessHandler(showLearners).getLearnerData();
      })();

      function showLearners(learners) {
        var learnerCheckboxes = $('#learners');
        learnerCheckboxes.empty();
        var cols=['a','b','c'];
        let i = 0;
        while( i < learners.length ) {
          let id = "fieldset" i;
          let fieldset = $('<fieldset  id="' id '"></fieldset>')
          learnerCheckboxes.append(fieldset);

          for (var j = 0; j < 3; j  ) {
            let div = $('<div ></div>')
            fieldset.append(div);
            id = "learner" i;
            let input = $('<input type="checkbox" name="learner" id="'   id   '" data-mini="true">');
            let label = $('<label for="'   id   '">'   learners[i][0]   '</label>' );
            div.append(input);
            div.append(label);
            i  ;
            if( i === learners.length ) break;
          }

        }
      }
    </script>
  </body>
</html>

Code.gs

function getLearnerData() {
  try {
    Logger.log("In getLearnerData");
    return [["Dave"],["Tom"],["Larry"],["Mary"],["Joe"],["Sam"],["John"]];
  }
  catch(err) {
    Logger.log("Error in getLearnerData: " err);
  }
}

Results

enter image description here

CodePudding user response:

Thanks TheWizEd for the idea to dynamically name the fieldset tags - this is what lead to the solution. By dynamically creating the fieldset ID, I can use the inner loop to append the checkboxes BETWEEN the fieldset tags. Here's the code:

function showLearners(learners) {
  var learnerCheckboxes = $('#learners');
  learnerCheckboxes.empty();
  var cols=['a','b','c'];
  var rowCount = 1;

  for (var i = 0; i < learners.length; i  ) {
    //in this next line, use rowCount to create a unique fieldset id
    learnerCheckboxes.append("<fieldset class=\"ui-grid-b\" id=\"checkRow"   rowCount   "\"></fieldset>");
    //then grab it
    var checkRow = $("#checkRow"   rowCount)
    for (var j = 0; j < cols.length; j  ) {
      //and append the checkboxes to the newly created fieldset
      checkRow.append(
        "<div class=\"ui-block-"   cols[j]   "\">"  
          "<div class=\"ui-checkbox ui-mini\">"  
            "<label for=\"learner"   i   "\" class=\"ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-checkbox-off\">"   
              learners[i][0]   "</label>"  
            "<input type=\"checkbox\" name=\"learner\" id=\"learner"   i   "\" data-mini=\"true\">"  
          "</div>"  
        "</div>"
      );
      i  ;//we're in the inner loop, so have to manually increment i
    }
    rowCount  ;
  }
}

  • Related