JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div ng-app="treeModule" ng-controller="TreelistController">
<tm-tree src="categories" fetch-children="fetchChildren()" select-node="toggleTree(node)"></tm-tree>
</div>
CSS
.treeNode {
min-height: 40px;
line-height: 40px;
font-size: 12px;
display:block;
}
.node {
display: inline-block;
border-bottom: 1px solid #e6e6e6;
}
.wholerow {
width: 100%;
cursor: pointer;
position: absolute;
left: 0;
border-bottom: 1px solid #e6e6e6;
}
ul {
list-style-type: none;
padding-left:20px;
lis:before {
content: "\e114";
display: inline-block;
font-family: 'Glyphicons Halflings';
font-weight: 400;
position: relative;
font-size: 10px;
display: inline-block;
width: 10px;
}
}
.collapsed ul {
display: none;
}
li.collapseds:before {
content: "\e080";
font-family: 'Glyphicons Halflings';
font-weight: 400;
position: relative;
font-size: 10px;
display: inline-block;
width: 10px;
}
li a:hover {
cursor: pointer;
}
JavaScript
var treeModule = angular.module('treeModule', []);
treeModule.directive('tmTree', function() {
return {
restrict: 'E', // tells Angular to apply this to only html tag that is <tree>
replace: true, // tells Angular to replace <tree> by the whole template
scope: {
t: '=src',
fetchChildren: '&fetchChildren',
selectNode : '&selectNode' // create an isolated scope variable 't' and pass 'src' to it.
},
controller : function($scope){
console.log('aaa');
},
template: '<ul><branch ng-repeat="c in t.children" src="c" fetch-children="fetchChildren()" select-Node="selectNode({node :child})" ng-class="c.expandChildren ? \'\':\'collapsed\' "></branch></ul>' ,
link: function(scope, element, attrs) {
}
};
});
treeModule.directive('branch', function($compile) {
return {
restrict: 'E', // tells Angular to apply this to only html tag that is <branch>
replace: true, // tells Angular to replace <branch> by the whole template
scope: {
b: '=src',
fetchChildren: '&fetchChildren', // create an isolated scope variable 'b' and pass 'src' to it.
selectNode : '&selectNode'
},
controller : function($scope,$element){
} ,
template: '<li class="treeNode"><div class="wholerow"></div><span id="chevron-right" class="glyphicon glyphicon-chevron-right" ></span><a ng-click="selectNode({child : b})">{{ b.text }}</a></li>',
link: function(scope, element, attrs) {
//// Check if there are any children, otherwise we'll have infinite execution
var has_children = angular.isArray(scope.b.children);
var parent = scope.b;
//// Manipulate HTML in DOM
if (has_children) {
element.append($compile( '<tm-tree src="b" fetch-children="fetchChildren()" select-Node="selectNode({node:child})" ></tm-tree>')(scope) );
// recompile Angular because of manual appending
...