JSFiddle - React, Tailwind, and code Playground
HTML
<ul>
<li>
<input id="chap1" type="checkbox" data-select-all="chapter1">
<label for="chap1">Chapter 1</label>
<ul>
<li>
<input id="sec1" type="checkbox" data-select-all="section1" data-select-some="chapter1">
<label for="sec1">Section 1</label>
<ul>
<li>
<input id="subsec1" type="checkbox" data-select-some="section1">
<label for="subsec1">SubSection 1</label>
</li>
<li>
<input id="subsec2" type="checkbox" data-select-some="section1">
<label for="subsec2">SubSection 2</label>
</li>
</ul>
</li>
<li>
<input id="sec2" type="checkbox" data-select-all="section2" data-select-some="chapter1">
<label for="sec2">Section 2</label>
</li>
</ul>
</div>
</li>
</ul>
CSS
ul {
padding-left: 10px;
}
JavaScript
$(function () {
/**
* Change all elements
*/
$("input[data-select-all]").change(function () {
select_all($(this));
});
/**
* Change some elements
*/
$("input[data-select-some]").change(function () {
select_some($(this));
});
/**
* Select all elements
*/
function select_all(element) {
var select = element.data("select-all");
if (select) {
$("input[data-select-some='" + select + "']").
prop("checked", element.prop("checked")).
each(function () {
select_all($(this));
});
}
}
/**
* Select some elements
*/
function select_some(element) {
var select = element.data("select-some");
if (select) {
if ($("input[data-select-some='" + select + "']:checked").length === 0 && $("input[data-select-some='" + select + "']:indeterminate").length === 0) {
$("input[data-select-all='" + select + "']").
prop("indeterminate", false).
prop("checked", false);
} else if ($("input[data-select-some='" + select + "']:not(:checked)").length === 0 && $("input[data-select-some='" + select + "']:indeterminate").length === 0) {
$("input[data-select-all='" + select + "']").
prop("indeterminate", false).
prop("checked", true);
} else {
$("input[data-select-all='" + select + "']").
prop("indeterminate", true);
}
select_some($("input[data-select-all='" + select + "']"));
}
}
});