How to find and check all dynamic child checkboxes in a tree using jquery?

I have added checkboxes on all items and successfully added functionality to select all checkboxes, but cannot make a selection for parent child checkboxes in the tree, if I select "Asia" it has to select all "Estern Asia" and "South Asia" if I choose Estern Asia, it must choose the whole country and vice versa.

var json ={"Asia": [{"regionList": [{"regionName": "Eastern Asia","Countrylist": [{"countryName": "China","subCountryList": [{"subCountryName": "Southern China"},{"subCountryName": "Eastern China"}]},{"countryName": "Hong Kong"}]},{"regionName": "Southern Asia","Countrylist": [{"countryName": "India"},{"countryName": "Pakistan"}]}]}]};
var html = '';
$.each(json, function(i1, object) {
html += '<li><input type="checkbox" /><b class=' + i1 + ' ><a name="' + i1 + '" >' + i1 + '</a></b>';
  $.each(object, function(i2, continent) {
    html += '<ul>';
    $.each(continent.regionList, function(i3, region) {
    	html += '<li><input type="checkbox" /><b>' + region.regionName + '</b>';
    	$.each(region.Countrylist, function(i4, country) {
    		html += '<ul><li><input type="checkbox" />' + country.countryName;
    		if (country.subCountryList) {
    		$.each(country.subCountryList, function(i5, subCountry) {
    			html += '<ul><li><input type="checkbox" />' + subCountry.subCountryName + '</li></ul>';
    		});
    	};
    	html += '</li></ul>';
    });
    html += '</li>';
  });
  html += '</ul>';
 });
 html += '</li>';
});

$('#regionContent ol').html(html);
$('#selectAll').click(function() {
  if(this.checked) {
	$('#regionContent input[type="checkbox"]').each(function() { 
		this.checked = true;               
	});
  }else{
	$('#regionContent input[type="checkbox"]').each(function() {
		this.checked = false;                       
	});
  }
});
      

li, ol{list-style:none;}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="regionContent">
    <input type="checkbox" id="selectAll">All Countries
    <ol></ol>
</div>
      

Run codeHide result


+3


source to share


3 answers


You can divide the work into two parts.

  • Check the child nodes according to the current checkbox.
  • Step through the parent nodes and mark their state according to their immediate child node state.

Edited:



var json = {
  Asia: [{
    regionList: [{
      regionName: "Eastern Asia",
      Countrylist: [{
        countryName: "China",
        subCountryList: [{
          subCountryName: "Southern China"
        }]
      }, {
        countryName: "Hong Kong"
      }]
    }, {
      regionName: "Southern Asia",
      Countrylist: [{
        countryName: "India"
      }, {
        countryName: "Pakistan"
      }]
    }]
  }]
};

var html = '';
$.each(json, function(i1, object) {
  html += '<li><input type="checkbox"/><b><a name="' + i1 + '" >' + i1 + '</a></b>';
  $.each(object, function(i2, continent) {
    html += '<ul>';
    $.each(continent.regionList, function(i3, region) {
      html += '<li><input type="checkbox"/><b>' + region.regionName + '</b><ul>';
      $.each(region.Countrylist, function(i4, country) {
        html += '<li><input type="checkbox"/>' + country.countryName;
        if (country.subCountryList) {
          html += '<ul>';
          $.each(country.subCountryList, function(i5, subCountry) {
            html += '<li><input type="checkbox"/>' + subCountry.subCountryName + '</li>';
          });
          html += '</ul>';
        };
        html += '</li>';
      });
      html += '</ul></li>';
    });
    html += '</ul>';
  });
  html += '</li>';
});

$(function() {
  $('#list').html(html);
  $('#regionContent').on('change', 'input[type=checkbox]', onChange);
});

var topNodes = function(chkbx) {
  return $(chkbx).closest('ul').closest('li');
};

var markTopNodes = function(nodes) {
  if (!nodes.length) return;
  var chkbx = nodes.children('input').eq(0); //parent checkbox
  //get the immediate li of the node
  var lis = nodes.children('ul').children('li');
  //get count of un-checked checkboxes
  var count = lis.children('input[type=checkbox]:not(:checked)').length;
  //mark if count is 0
  chkbx.prop('checked', !(count));
  //recursive call for other top nodes
  markTopNodes(topNodes(chkbx));
};

var onChange = function(e) {
  //for child nodes, checked state = current checkbox checked state
  $(this).closest('li').find('input[type=checkbox]').prop('checked', this.checked);
  //for parent nodes, checked if immediate childs are checked, but recursively
  markTopNodes(topNodes(this));
};
      

li {
  list-style: none;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div id="regionContent">
  <ul>
    <!-- updated the html here -->
    <li>
      <input type='checkbox' />All Countries
      <ul id='list'></ul>
      <!-- added this -->
      <li>
  </ul>
</div>
      

Run codeHide result


+2


source


try something along these lines:



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

      

0


source


Listed below are all child checkboxes deeper than 1 level using find

, and not children

.

$(document.body).on('change', 'input[type=checkbox]', function(){
    if($(this).is(':checked')){
        $(this).find('input[type="checkbox"]').prop('checked', true);
    }
});

      

0


source







All Articles