JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-tree/2.22.1/angular-ui-tree.min.js"></script>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-tree/2.22.1/angular-ui-tree.min.css">
<div ng-app="app">
<div ng-controller="treeCtrl">
<div ui-tree id="tree-root">
<ol ui-tree-nodes ng-model="data">
<li ng-repeat="node in data" ui-tree-node ng-include="'nodes_renderer.html'"></li>
</ol>
</div>
</div>
<script type="text/ng-template" id="nodes_renderer.html">
<div ui-tree-handle class="tree-node tree-node-content">
<a class="btn btn-success btn-xs" ng-if="node.nodes && node.nodes.length > 0" data-nodrag ng-click="toggle(this)"><span
class="glyphicon"
ng-class="{
'glyphicon-chevron-right': collapsed,
'glyphicon-chevron-down': !collapsed
}"></span></a> {{node.title}}
<a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="remove(this)"><span
class="glyphicon glyphicon-remove"></span></a>
<a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="newSubItem(this)" style="margin-right: 8px;"><span
class="glyphicon glyphicon-plus"></span></a>
</div>
<ol ui-tree-nodes="" ng-model="node.nodes" ng-class="{hidden: collapsed}">
<li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer.html'">
</li>
</ol>
</script>
</div>
CSS
.btn {
margin-right: 8px;
}
.angular-ui-tree-handle {
background: #f8faff;
border: 1px solid #dae2ea;
color: #7c9eb2;
padding: 10px;
}
.angular-ui-tree-handle:hover {
color: #438eb9;
background: #f4f6f7;
border-color: #dce2e8;
}
.angular-ui-tree-placeholder {
background: #f0f9ff;
border: 2px dashed #bed2db;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
tr.angular-ui-tree-empty {
height: 100px;
}
.group-title {
background-color: #687074!important;
color: #fff!important;
}
.tree-node {
border: 1px solid #dae2ea;
background: #f8faff;
color: #7c9eb2;
}
.nodrop {
background-color: #f2dede;
}
.tree-node-content {
margin: 10px;
}
.tree-handle {
background: #428bca;
color: #fff;
margin-right: 10px;
padding: 10px;
}
JavaScript
var app = angular.module('app', ['ui.tree']);
app.controller('treeCtrl', function($scope) {
$scope.data = [{
'id': 1,
'title': 'tree1 - item1',
'nodes': []
}, {
'id': 2,
'title': 'tree1 - item2',
'nodes': []
}, {
'id': 3,
'title': 'tree1 - item3',
'nodes': []
}, {
'id': 4,
'title': 'tree1 - item4',
'nodes': []
}];
$scope.remove = function(scope) {
scope.remove();
};
$scope.toggle = function(scope) {
scope.toggle();
};
$scope.moveLastToTheBeginning = function() {
var a = $scope.data.pop();
$scope.data.splice(0, 0, a);
};
$scope.newSubItem = function(scope) {
var nodeData = scope.$modelValue;
nodeData.nodes.push({
id: nodeData.id * 10 + nodeData.nodes.length,
title: nodeData.title + '.' + (nodeData.nodes.length + 1),
nodes: []
});
};
$scope.collapseAll = function() {
$scope.$broadcast('angular-ui-tree:collapse-all');
};
$scope.expandAll = function() {
$scope.$broadcast('angular-ui-tree:expand-all');
};
});