JSFiddle - React, Tailwind, and code Playground
by Akram kamal
HTML
<form>
<input type="checkbox" name="parent" id="parent" data-children="#child1, #child2, #child3" /><label for="parent">Parent</label>
<ul>
<li>
<input type="checkbox" name="child1" id="child1" />
<label for="child1">Child 1</label>
</li>
<li>
<input type="checkbox" name="child2" id="child2" data-children="#child2sub1, #child2sub2" />
<label for="child2">Child 2</label><ul>
<li><input type="checkbox" name="child2sub1" id="child2sub1" /><label for="child2sub1">Child 2 SubChild 1</label></li>
<li><input type="checkbox" name="child2sub2" id="child2sub2" /><label for="child2sub2">Child 2 SubChild2</label></li>
</ul>
</li>
<li>
<input type="checkbox" name="child3" id="child3" data-children="#child3sub1, #child3sub2" />
<label for="child3">Child 3</label>
<ul>
<li>
<input type="checkbox" name="child3sub1" id="child3sub1" />
<label for="child3sub1">Child 3 SubChild 1</label>
</li>
<li>
<input type="checkbox" name="child3sub2" id="child3sub2" data-children="#child3sub2sub1, #child3sub2sub2" />
<label for="child3sub2">Child 3 SubChild 2</label>
<ul>
<li><input type="checkbox" name="child3sub2sub1" id="child3sub2sub1" /><label for="child3sub2sub1">Child 3 SubChild 2 SubChild 1</label></li>
<li><input type="checkbox" name="child3sub2sub2" id="child3sub2sub2" /><label for="child3sub2sub2">Child 3 SubChild 2 SubChild 2</label></li>
</ul>
</li>
</ul>
</li>
</ul>
<input type="checkbox" name="parent2" id="parent2" data-children="#p2child1, #p2child2" /><label for="parent2">Parent</label>
<ul>
<li>
...
JavaScript
(function($) {
$('input[type=checkbox][data-children]').unbind("change childchange childchangebubble").each(function() {
var parent = $(this);
var linkedChildren = $(parent.data("children"));
//trigger a "childChange" event on the parent when any child is triggered.
linkedChildren.bind("change childchangebubble", function() {
parent.trigger("childchange");
});
parent.bind({
"change": function(event) { // Bind change event to check all children
linkedChildren.prop("checked", parent.prop("checked")).trigger("change");
},
"childchange": function() { // have to bind custom event seperately, there seems to be a jQuery bug.
// When a child is changed recalculate if parent should be checked
var noChildrenUnchecked = !linkedChildren.is(":not(:checked)");
parent.prop("checked", noChildrenUnchecked).trigger("childchangebubble");
}
});
});
})(jQuery);