<!DOCTYPE html>
<html ng-app="tree">
<head>
<link data-require="bootstrap-css@*" data-semver="3.0.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css" />
<link data-require="font-awesome@3.2.1" data-semver="3.2.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" />
<script data-require="angular.js@1.0.8" data-semver="1.0.8" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="bootstrap@2.3.2" data-semver="2.3.2" src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script data-require="lodash.js@2.3.0" data-semver="2.3.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="TreeController">
<h2 ng-bind="title" class="alert alert-success"></h2>
<ul class="tree-container">
<li style="margin: 5px; list-style: none;" ng-repeat="d in getChildren()" ng-include="'tree_item_renderer.html'"></li>
</ul>
</div>
</body>
<script type="text/ng-template" id="tree_item_renderer.html">
<i ng-show="!d.$expand && hasChildren(d.id)" class="icon-plus" ng-click="d.$expand = !d.$expand"></i>
<i ng-show="d.$expand && hasChildren(d.id)" class="icon-minus" ng-click="d.$expand = !d.$expand"></i>
<span ng-show="!hasChildren(d.id)" style="margin-left:16px"></span>
{{d.label}}
<ul>
<li style="list-style:none;" ng-repeat="d in getChildren(d.id)" ng-include="'tree_item_renderer.html'"></li>
</ul>
</script>
</html>
// Code goes here
angular.module('tree', [])
.controller('TreeController', function($scope) {
$scope.title = "Tree";
$scope.data = [
{id: '1', label: 'root', parentId: 'null', $expand: true},
{id: '2', label: 'child 11', parentId: '1', $expand: false},
{id: '3', label: 'child 12', parentId: '1', $expand: false},
{id: '4', label: 'child 13', parentId: '1', $expand: false},
{id: '5', label: 'child 14', parentId: '1', $expand: false},
{id: '6', label: 'child 111', parentId: '2', $expand: false},
{id: '7', label: 'child 1111', parentId: '6', $expand: false},
{id: '8', label: 'child 121', parentId: '3', $expand: false},
{id: '9', label: 'child 122', parentId: '3', $expand: false},
{id: '9', label: 'child 131', parentId: '4', $expand: false}
];
$scope.getChildren = function(parentId) {
if(!parentId) {
return [$scope.data[0]];
}
if(!_($scope.data).where({id: parentId}).value()[0]['$expand']) {
return [];
}
return _($scope.data).where({parentId: parentId}).value();
}
$scope.hasChildren = function(id) {
if(!id) {
return (_($scope.data).where({parentId: $scope.data[0].id}).value().length !== 0);
}
return (_($scope.data).where({parentId: id}).value().length !== 0);
}
});
/* Styles go here */
.tree-container {
height: 100%;
color: #444;
font-weight: 200;
}
i {
cursor: pointer;
}