samedi 7 mai 2022

Indeterminate checkboxes not working with for loop generated from JSON

I'm trying to build a nested checkbox with a hierarchy level by using a loop. It works perfectly but without the combination of a function to change the indeterminate status for checkboxes. I also tried to generate the same HTML code to build checkboxes and check if the function is working. The checkboxes that were built manually work well with indeterminate status.

let data = {
  "Tall Things": {
    "label": "Tall Things",
    "children": {
      "Buildings": {
        "label": "Buildings",
      },
      "Two sandwiches": {
        "label": "Two sandwiches",
      },
      "Giants": {
        "label": "Giants",
        "children": {
          "Andre": {
            "label": "Andre",
          },
          "Paul Bunyan": {
            "label": "Paul Bunyan",
          }
        }
      }
    }
  }
}

let nodeLevel = 1;
function addItem(parentUL, branch, parentName) {
  for (var key in branch) {
    var item = branch[key].children;

    let name = '';

    if (parentName) {
      name = parentName;
    }

    $item = $('<li>', {
      id: key,
    });
    $item.append($('<input>', {
      type: "checkbox",
      id: key,
      name: key,
      value: key,
      "data-parent": name,
    }));
    $item.append($('<label>', {
      for: key,
      text: key
    }));
    parentUL.append($item);
    nodeLevel++;
    if (branch[key].children) {
      var $ul = $('<ul>', {
        //style: 'display: none'
      }).appendTo($item);

      addItem($ul, item, branch[key].label);
    } else {
      nodeLevel = 1;
    }
  }
}

// On default load
$(document).ready(function(){
  addItem($('#sb'), data);

  $('input[type="checkbox"]').prop("checked", "true");

   $('label').click(function(){
    $(this).closest('li').children('ul').slideToggle();  
  });  

});

$('input[type="checkbox"]').change(function(e) {

  var checked = $(this).prop("checked"),
      container = $(this).parent(),
      siblings = container.siblings();

  container.find('input[type="checkbox"]').prop({
    indeterminate: false,
    checked: checked
  });

  function checkSiblings(el) {

    var parent = el.parent().parent(),
        all = true;

    el.siblings().each(function() {
      let returnValue = all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
      return returnValue;
    });
    
    if (all && checked) {

      parent.children('input[type="checkbox"]').prop({
        indeterminate: false,
        checked: checked
      });

      checkSiblings(parent);

    } else if (all && !checked) {

      parent.children('input[type="checkbox"]').prop("checked", checked);
      parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
      checkSiblings(parent);

    } else {

      el.parents("li").children('input[type="checkbox"]').prop({
        indeterminate: true,
        checked: false
      });

    }

  }

  checkSiblings(container);
});
ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

li {
}

ul ul {
  margin: 0 0 0 30px;
}
<input type="checkbox" name="selectAll" id="selectAll"><label>Select All</label>
<p>Nested checkboxes using loop to generated items. Not working with indeterminate status.</p>

<ul id="sb"></ul>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<br>
<p>Nested checkboxes without using loop to generated items. Working with indeterminate status.</p>
<ul>
  <li id="Tall Things">
    <input type="checkbox">
    <label>Tall Things</label>
    <ul style="">
      <li id="Buildings">
        <input type="checkbox">
        <label>Buildings</label>
      </li>
      <li id="Giants">
        <input type="checkbox">
        <label>Giants</label>
        <ul style="">
          <li id="Andre">
            <input type="checkbox">
            <label>Andre</label>
          </li>
          <li id="Paul Bunyan">
            <input type="checkbox">
            <label>Paul Bunyan</label>
          </li>
        </ul>
      </li>
      <li id="Two sandwiches">
        <input type="checkbox">
        <label>Two sandwiches</label>
      </li>
    </ul>
  </li>

</ul>

May I know where is the error?




Aucun commentaire:

Enregistrer un commentaire