Angular: Empty Fiddle
http://angularjs.org/
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script type="text/ng-template" id="tree_item_renderer.html">
<div class="node" ng-class="{selected: node.selected}" ng-click="select()">
<span ng-click="node.opened=!node.opened" style="display:inline-block; width:10px;">
<span ng-show="!node.opened && node.children.length > 0" class="fa fa-caret-right">+</span>
<span ng-show="node.opened && node.children.length > 0" class="fa fa-caret-down">-</span>
</span>
<span ng-show="!node.editting" ng-click="node.selected && edit($event)">{{node.name}}</span>
<span ng-show="node.editting"><input ng-model="node.name" ng-blur="unedit()"></input></span>
<button ng-click="add()">Add node</button>
<button ng-click="delete()" ng-show="node.parent">Delete node</button>
</div>
<ul ng-show="node.opened" style="list-style-type: none; padding-left: 15px">
<li ng-repeat="node in node.children">
<recursive><sub-tree node="node"></sub-tree></recursive>
</li>
</ul>
</script>
<ul ng-app="Application" style="list-style-type: none; padding-left: 0">
<tree node='{name: "Node", children: [], opened:true}'></tree>
</ul>
CSS
.node:hover {
width: 100%;
background-color: #e7f4f9;
}
.selected, .selected:hover{
background-color: #0069da;
color: white;
}
JavaScript
/*
Is it possible to make a Tree View with Angular?
http://stackoverflow.com/questions/11854514/is-it-possible-to-make-a-tree-view-with-angular
*/
angular.module("myApp",[]);
/* http://stackoverflow.com/a/14657310/1309218 */
angular.module("myApp").
directive("recursive", function($compile) {
return {
restrict: "EACM",
priority: 100000,
compile: function(tElement, tAttr) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents);
}
compiledContents(scope,
function(clone) {
iElement.append(clone);
});
};
}
};
});
angular.module("myApp").
directive("subTree", function($timeout) {
return {
restrict: 'EA',
require: '^tree',
templateUrl: 'tree_item_renderer.html',
scope: {
node: '=',
},
link: function(scope, element, attrs, treeCtrl) {
scope.select = function(){
treeCtrl.select(scope.node);
};
scope.delete = function() {
scope.data.parent.children.splice(scope.node.parent.children.indexOf(scope.data), 1);
};
scope.add = function() {
var post = scope.node.children.length + 1;
var newName = scope.node.name + '-' + post;
scope.node.children.push({name: newName, children: [], opened:true, parent: scope.node});
};
scope.edit = function(event){
scope.node.editting = true;
$timeout(function(){event.target.parentNode.querySelector('input').focus();});
};
scope.unedit = function(){
scope.node.editting...