tree data structure using Angularjs

tree data structure using Angularjs and bootstrap

by sazakharov

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-route.min.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.js"></script>
<div ng-app ng-controller="MainCtrl" ng-csp="">
  <div class="container-fluid" style="padding-left : 25px;">

    <br>
    <br>
    <br>
    <div class="row">
      <div class="col-md-8 col-md-offset-2">
        <span class="label label-default ng-binding" style="font-size : 25px">
                        Tree Data Structure Implementation Using Bootstrap Table
                    </span>
      </div>
    </div>
    <br>
    <br>
    <br>

    <div class="row">
      <div class="col-md-3">
        <button ng-click="addNewNodeAtRootLevel()" type="button" class="btn btn-primary btn-sm">Add New Node</button>
      </div>
    </div>

    <br>
    <div class="row">
      <div class="col-md-12">
        <table class="table table-hover table-bordered" id="mytable" style="width: 90%;">
          <caption></caption>
          <thead>
            <tr class="info">
              <th data-toggle="tooltip" data-placement="top" title="click here to expand/close" ng-click="expandAll()">
                Name

                <span ng-if="!showAll" class="glyphicon glyphicon-triangle-right" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Help: expand all nodes">
                                </span>

                <span ng-if="showAll" class="glyphicon glyphicon-triangle-bottom" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Help: ">
                                </span>

              </th>
              <th>Id</th>
              <th>Operations</th>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="node in nodesTableArr | filter : {isShow :...

CSS

.level0 {
  text-indent: 0px;
  color: #428bca;
}

.level1 {
  text-indent: 20px;
  color: #428bca;
}

.level2 {
  text-indent: 40px;
  color: #428bca;
}

.level3 {
  text-indent: 60px;
  color: #428bca;
}

.level4 {
  text-indent: 80px;
  color: #428bca;
}

.level5 {
  text-indent: 100px;
  color: #428bca;
}

.level6 {
  text-indent: 120px;
  color: #428bca;
}

.hasDropdown {
  color: #428bca;
}

.noDropdown {
  color: #000000;
}

div.tooltip-inner {
  text-align: center;
  -webkit-border-radius: 0px;
  -moz-border-radius: 0px;
  border-radius: 0px;
  margin-bottom: 6px;
  background-color: #505050;
  font-size: 14px;
}

JavaScript

function MainCtrl($scope) {
  // add new node at top level here
  $scope.isAddExamNode = false;
  $scope.addNewNodeAtRootLevel = function() {
    $scope.isAddExamNode = true;
    var newNode = {
      name: "new node",
      id: "",
      level: 0,
      parent: "root",
      toggleStatus: false,
      parentId: -1,
      isShow: true,
      isEditable: false,
      childCount: 0,
      isSaveBtn: false,
      isShowMessage: false,
      type: "exam"
    };
    $scope.nodesTableArr.unshift(newNode);
  };

  // add new node.
  $scope.operationStatusMessage = "";
  $scope.currentNodeSelected = {};
  var uniqueIdForNewNodes = 0;
  $scope.addChildNode = function(node) {
    // add row to table.
    $scope.operationStatusMessage = "";
    $scope.currentNodeSelected = node;
    for (var i = 0; i < $scope.nodesTableArr.length; i++) {
      if ($scope.nodesTableArr[i].id == node.id) {
        $scope.nodesTableArr.splice(i + 1, 0, {
          name: "new node",
          id: uniqueIdForNewNodes,
          level: node.level + 1,
          parent: node.name,
          toggleStatus: false,
          parentId: node.id,
          isShow: true,
          isEditable: false,
          childCount: 0,
          isSaveBtn: false,
          isShowMessage: false,
          type: "nonExam"
        });
        break;
      }
    }

    uniqueIdForNewNodes += 1;
  };

  $scope.saveNewNode = function(node, isExamNode) {
    alert("You can send request on server to add this node here.");
    $scope.saveNewNodeCB();
  };

  $scope.saveNewNodeCB = function() {
    $scope.resetOperationStatusMessage();
    $scope.operationStatusMessage = "node Saved Successfully";
    $scope.currentNodeSelected.isShowMessage = true;
    $scope.currentNodeSelected.isSaveBtn = false;

    // update node id in newly added node object, so that if we add new node under it, it has its valid parent id.
    for (var i = 0; i < $scope.nodesTableArr.length; i++) {
      var node = $scope.nodesTableArr[i];
      if (node...