JSFiddle - React, Tailwind, and code Playground
HTML
<body ng-app>
<div ng-controller="Ctrl">
<ul>
<li>
<input type="checkbox" value="allChecks.id" ng-model="allChecks.isChecked" ng-change="checkChange(allChecks)" />
<label>{{allChecks.id}}</label>
</li>
<li ng-repeat="child in allChecks.children">
<input type="checkbox" ng-model="child.isChecked" ng-change="checkChange(child)" />
<label>{{child.id}}</label>
<ul>
<li ng-repeat="grandchild in child.children">
<input type="checkbox" ng-model="grandchild.isChecked" ng-change="checkChange(grandchild)" />
<label>{{grandchild.id}}</label>
<ul>
<li ng-repeat="grandgrandchild in grandchild.children">
<input type="checkbox" ng-model="grandgrandchild.isChecked" ng-change="checkChange(grandgrandchild)" />
<label>{{grandgrandchild.id}}</label>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
JavaScript
function Ctrl($scope) {
function Node(id, isChecked, parent) {
this.id = id;
this.isChecked = isChecked;
this.parent = parent;
this.children = [];
}
var parent = new Node('ALL', true, "");
var child1 = new Node('Group1', true, parent);
var gchild1 = new Node('Host1', true, child1);
child1.children.push(gchild1);
var ggchild111 = new Node('Node 1', true, gchild1);
var ggchild222 = new Node('Node 2', true, gchild1);
var ggchild333 = new Node('Node 3', true, gchild1);
gchild1.children.push(ggchild111, ggchild222, ggchild333);
var child2 = new Node('Group2', true, parent);
var gchild2 = new Node('Host1', true, child1);
var gchild3 = new Node('Host2', true, child2);
var ggchild11 = new Node('Node 1', true, gchild3);
var ggchild22 = new Node('Node 2', true, gchild3);
var ggchild33 = new Node('Node 3', true, gchild3);
var ggchild1 = new Node('Node 1', true, gchild2);
var ggchild2 = new Node('Node 2', true, gchild2);
var ggchild3 = new Node('Node 3', true, gchild2);
gchild2.children.push(ggchild1, ggchild2, ggchild3);
gchild3.children.push(ggchild11, ggchild22, ggchild33);
child2.children.push(gchild3, gchild2);
parent.children.push(child1, child2);
$scope.allChecks = parent;
function parentCheckChange(item) {
for (var i in item.children) {
item.children[i].isChecked = item.isChecked;
if (item.children[i].children) {
parentCheckChange(item.children[i]);
}
}
}
function childCheckChange(parent) {
var allChecks = true;
for (var i in parent.children) {
if (!parent.children[i].isChecked) {
allChecks = false;
break;
}
}
if (allChecks) {
parent.isChecked = true;
}
else {
parent.isChecked = false;
}
if (parent.parent) {
childCheckChange(parent.parent);
}
}
$scope.checkChange = function(item) {
// We're handling the ALL checkbox here
if...