Angular Tree
by heavyhorse
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/ng-template" id="tree_item_renderer.html">
<span ng-class="'depth-'+node.depth" ng-click="expand($event)">
<pre ng-show="node.nodes.length > 0">▲</pre>
<pre ng-show="node.nodes.length == 0"> </pre>
{{ node.name }}
</span>
<ul class="subtree">
<li ng-repeat="node in node.nodes track by $index" ng-include="'tree_item_renderer.html'"></li>
</ul>
</script>
<ul ng-controller="TreeController">
<!-- <button ng-click="walk(tree, 0)">Walk</button> -->
<li ng-repeat="node in tree track by $index" ng-include="'tree_item_renderer.html'"></li>
</ul>
CSS
* {
-webkit-user-select: none;
user-select: none;
}
ul {
list-style: circle;
}
li {
font-family: monospace;
cursor: pointer;
}
span {
padding: 2px;
display: block;
border: 1px solid rgba(0,0,0,0);
}
span pre {
display: inline-block;
}
span:hover {
background: #7fdbff;
color: black;
}
span:focus, span:active, .active {
border: 1px solid #001f3f;
background: #001f3f;
color: #80BFFF;
}
.depth-0 { padding-left: 15px; }
.depth-1 { padding-left: 30px; }
.depth-2 { padding-left: 45px; }
.depth-3 { padding-left: 60px; }
.depth-4 { padding-left: 75px; }
.depth-5 { padding-left: 90px; }
.depth-6 { padding-left: 105px; }
.depth-7 { padding-left: 16px; }
.depth-8 { padding-left: 18px; }
.depth-9 { padding-left: 20px; }
JavaScript
angular.module('app', [])
.controller('TreeController', function($scope, $timeout) {
$scope.tree = [
{ name: 'root', nodes: [], depth: -1 }
];
var treeDepth = 5;
function generate(node, depth) {
if(depth <= treeDepth) {
var maxNodes = _.random(1, 5);
_(maxNodes).times(function(i) {
node.nodes.push({name: 'node @ ('+depth+','+i+')', nodes: [], depth: depth });
generate(node.nodes[i], depth+1);
});
} else {
return;
}
}
generate($scope.tree[0], 0);
$timeout(function() {
$scope.$apply();
}, 500);
$scope.add = function(node) {
node.nodes.push({ name: 'node', nodes: [] });
};
$scope.expand = function($event) {
console.log($event);
angular.element('span').removeClass('active');
angular.element($event.target).addClass('active');
};
})
;