JSFiddle - React, Tailwind, and code Playground
by Amit Thakkar
HTML
<div ng-app="tree">
<div ng-controller="TreeController as tc">
<ul class="tree">
<node-tree children="tc.tree"></node-tree>
</ul>
</div>
<script type="text/ng-template" id="node.html">
<li>
<input ng-click="checkNode(node)" type="checkbox" ng-checked="node.checked">
<span ng-click="toggleVisibility(node)">
{{ $index + 1 }}. {{ node.name }}
</span>
</li>
</script>
</div>
CSS
ul.tree {
list-style: none;
}
ul.tree > li {
margin: 10px;
}
ul.tree > li > span {
cursor: pointer;
}
JavaScript
// Tree Controller
(function (ng) {
var app = ng.module('tree', ['tree.directives']);
app.controller("TreeController", [function () {
var tc = this;
buildTree();
function buildTree() {
tc.tree = JSON.parse('[{"name":"Vegetarian Recipes","checked":false,"children":[{"name":"Fruits","checked":false,"children":[{"name":"Dry Fruits","checked":false,"children":[{"name":"Almond","checked":false},{"name":"Apricot","checked":false},{"name":"Cashewnuts","checked":false},{"name":"Dates","checked":false},{"name":"Walnuts","checked":false},{"name":"Peanuts","checked":false},{"name":"Pistachios","checked":false}]},{"name":"Fresh Fruits","checked":false,"children":[{"name":"Apple","checked":false},{"name":"Banana","checked":false},{"name":"Orange","checked":false},{"name":"Mango","checked":false},{"name":"Grapes","checked":false}]}]},{"name":"Soup","checked":false,"children":[{"name":"Tomato Soup","checked":false},{"name":"Loaded Potato Soup","checked":false},{"name":"French Onion Soup","checked":false}]}]},{"name":"Non-vegetarian Recipes","checked":false}]');
}
}]);
})(angular);
// Tree directives
(function (ng) {
var app = ng.module('tree.directives', []);
app.directive('nodeTree', function () {
return {
template: '<node ng-repeat="node in tree"></node>',
replace: true,
restrict: 'E',
scope: {
tree: '=children'
}
};
});
app.directive('node', function ($compile) {
return {
restrict: 'E',
replace: true,
templateUrl: 'node.html', // HTML for a single node.
link: function (scope, element) {
/*
* Here we are checking that if current node has children then compiling/rendering children.
* */
if (scope.node && scope.node.children && scope.node.children.length > 0) {
var childNode = $compile('<ul class="tree" ng-if="!node.visibility"><node-tree children="node.children"></node-tree></ul>')(scope);
element.append(childNode);
}
},
controller: ["$scope",...