Search code examples
jquerygoogle-apps-scriptjquery-mobile

Checkbox styles not applying when loading data asynchronously


Using google apps script to build a simple tool at my school to help collect photo evidence of students work and save it centrally so all teaching staff can access it (there's probably an app already to do this, but I thought it could be a non-complicated and useful way to learn some more coding).

The problem I am having is that checkboxes that are loaded asynchronously (based on data from a spreadsheet of students) are not getting styled. If I hardcode some sample checkboxes, using the styling that my dynamic code generates, the styles are applied perfectly (see this screenshot to see the difference)

Here's the bits of code I am using to do this...

Trigger the function that generates the checkboxes

<script>
  window.addEventListener('load', function() {
    console.log('Page is loaded');
  });
</script>

$(function() {
  google.script.run.withSuccessHandler(showLearners)
      .getLearnerData();
});
//Please note the getLearnerData() code works fine, so won't show that

showLearners script This is embedded at the end of the page.

function showLearners(learners) {
  //split learners into staff and students

  var learnersObj = {staff:[], students:[]}
  //var staff = [];
  //var students = [];
  for (var i=0; i<learners.length; i++) {
    if (learners[i][3] === "student" || learners[i][3] === '') {
      learnersObj.students.push(learners[i]);
    } else {
      learnersObj.staff.push(learners[i])
    }
  }

  var roles = ["staff", "students"];
  var cols=['a','b','c'];
  var r = 0;

  //This loop creates checkboxes for students and then staff
  while(r < roles.length) {
    var role = roles[r];
    var rowCount = 1;
    var learnerCheckboxes = $('#' + role);
  
    //This loop creates the fieldset groups
    for (var i = 0; i < learnersObj[role].length; i++) {
      learnerCheckboxes.append("<fieldset id=\"checkRow" + role + rowCount + "\">")
      var fieldSet = $("#checkRow" + role + rowCount).addClass("ui-grid-b");

      //This loop creates 3 checkboxes in each grid of the fieldset
      for (var j = 0; j < cols.length; j++) {
        var learnerID = learnersObj[role][i][0];
        fieldSet.append("<div id=\"checkRow" + role + rowCount + "-" + cols[j] + "\">");
        var div = $("#checkRow" + role + rowCount + "-" + cols[j]).addClass("ui-block-" + cols[j]);
        div.append(
            "<input type=\"checkbox\" name=\"learner\" id=\"learner" + role + i + "\"  data-mini=\"true\"/>" +
            "<label for=\"learner" + role + i + "\">" + learnerID + "</label>"
          );
        if (j < (cols.length-1)) {
          i++;//we're in the inner loop, so have to manually increment i, but not if we're near the end
        }
        if (i >= learnersObj[role].length) {
          break;
        }
      }
      fieldSet.trigger("create");
      rowCount++;
    }
    r++;
  }

  $('#loader').hide();
  $('#photoForm').show();
  $('#staff').hide();
  console.log("Learners loaded")
} //end showLearners()

This code generates output below (just one row shown) that matches the jquery demos (here):

<fieldset id="checkRow1" class="ui-grid-b">
  <div id="checkRow1-a" class="ui-block-a">
    <input type="checkbox" name="learner" id="learner0" data-mini="true">
    <label for="learner0">David</label>
  </div>
  <div id="checkRow1-b" class="ui-block-b">
    <input type="checkbox" name="learner" id="learner1" data-mini="true">
    <label for="learner1">Dominic</label>
  </div>
  <div id="checkRow1-c" class="ui-block-c">
    <input type="checkbox" name="learner" id="learner2" data-mini="true">
    <label for="learner2">Eliza</label>
  </div>
</fieldset>

I am guessing the problem is to do with the timing - i.e. because these checkboxes are added after the page is loaded, some of the styling from the embedded jquery-mobile stylesheets aren't being applied. I had hoped that using jquery functions to add styles (.addclass()) would have solved this, but it hasn't.

Thx in advance for any help


Solution

  • It seems adding fieldSet.trigger("create") applies the CSS styles correctly. You can check this JSFiddle: https://jsfiddle.net/zpLbr26y/21/