0

I'm new to angularjs and want to implement some hierarchy screen in which user can add a new group, child to that group and so on. (parent/child hierarchy)

Something like this

1 Admin

1.1 -----User Admin

1.1.1 ----------Tech Support Admin

1.1.1.1 --------------------Tech Support Team

1.2 ----------Login Admin

1.2.1 --------------------Profiles

1.3 -----Client Admin

1.3.1 ----------Client 1

1.3.2 ----------Client 2

2 Users

2.1 -----User 1

2.2 -----User 2

2.3 -----User 3

I've searched some tutorials and the only solution I found out relative to my problem is angular ui tree.

But I'm not satisfied with that because I have to add images/avatar with all nodes (parents/children), then have to assign some roles to each of them on the basis of their parent node. but ui-tree does not have any procedure to add customized nodes or child of any node.

Is there any better approach to do this? Any kind of help will be appreciated.

Community
  • 1
  • 1
Naila Akbar
  • 3,033
  • 4
  • 34
  • 76
  • _"ui-tree does not have any procedure to add customized nodes or child of any node"_ I don't understand your concerns. You can design the nodes however you like them to be. – a better oliver Jan 26 '17 at 14:41

3 Answers3

2

To implement following structure there is property name $parentNodesScope added to get parent index so i added {{this.$parentNodesScope.$parentNodesScope.$index+1}}. {{this.$parentNodesScope.$index+1}}. {{$index+1}} {{node.title}}

1 Admin

1.1 -----User Admin

1.1.1 ----------Tech Support Admin

1.1.1.1 --------------------Tech Support Team

1.2 ----------Login Admin

1.2.1 --------------------Profiles

1.3 -----Client Admin

1.3.1 ----------Client 1

1.3.2 ----------Client 2

2 Users

2.1 -----User 1

2.2 -----User 2

2.3 -----User 3

Here is my jsfiddle link jsfiddle

Arvind Pal
  • 498
  • 3
  • 14
1

I rolled my own solution on something similar. I can't remember why I didn't go with ui-tree. What I needed was a way to recursively create views so that I could mimic a filesystem. Here's the plunk from when I was proofing it out. This should be simpler for you since you're not trying to split files and folders like I did.

With the recursion helper I was able to declare my data structure like this:

$scope.items = [
  new File('item1', '/item1', 11, false),
  new File('item2', '/item2', 22, true),
  new File('item3', '/item3', 33, false),
  new File('A Really Long File Name Should Go Here', '/item4', 44, false),
  new Folder('Folder 1', '/folder1', [new File('item5', '/item5', 55, false)], false)
];

And I could render it using this:

<table class="table table-condensed table-responsive">
<tbody>
    <tr>
      <th></th>
      <th>Name</th>
      <th>Size</th>
      <th></th>
    </tr>
    <tr ng-repeat="item in getFiles()">
      <td class="minWidth4px">
        <input type="checkbox" ng-model="item.isSelected" />
      </td>
      <td class="truncateName">
        {{item.name}}
      </td>
      <td class="minWidth4px">{{item.size}}mb</td>
      <td ng-show="item.canPreview()" class="minWidth4px">
        <button class="btn" ng-click="openPreview(item)">Preview</button>
      </td>
    </tr>
    <tr ng-repeat="item in getFolders()" ng-click="openFolder(item)">
      <td class="minWidth4px">
        <i ng-show="item.isOpen" class="fa fa-folder-open-o"></i>
        <i ng-hide="item.isOpen" class="fa fa-folder-o"></i>
      </td>
      <td colspan="3">
        <label>{{item.name}}</label>
        <attachments ng-show="item.isOpen" items="item.items"></attachments>
      </td>
    </tr>
  </tbody>
</table>

And here's the directive for the attachements:

var attachmentsLink = function($scope) {
  $scope.openFolder = function(folder) {
    folder.isOpen = !folder.isOpen;
    console.log(folder);
  };

  $scope.getFiles = function() {
    return $scope.items.filter(function(x) {
      return x instanceof File;
    });
  };

  $scope.getFolders = function() {
    return $scope.items.filter(function(x) {
      return x instanceof Folder;
    });
  };
};

var attachmentsController = function($scope, previewService){
  $scope.openPreview = function(file) {
    previewService.preview = file;
    previewService.showPreview = true;
  };
};

var attachments = function(RecursionHelper) {
  return {
    compile: function(element) {
      return RecursionHelper.compile(element, attachmentsLink);
    },
    controller: attachmentsController,
    restrict: 'E',
    scope: {
      items:'=',
    },
    templateUrl: 'attachments.html'
  };
};

angular.module("app").directive("attachments", attachments);

I can't take credit for the recursion helper that is the meat of it. The recursion helper is here Hope this helps.

dwbartz
  • 886
  • 10
  • 13
1

Long time.. let me post my solution here..may be it helps someone else..

So basically I did this with the help of angular-ui-tree with some custom changes to add avatar and links etc. here is html code;

<div class="panel-body">
     <div class="col-sm-12">
        <div ui-tree id="tree-root" ng-if="data.length > 0" data-drop-enabled="false" data-drag-enabled="false" data-nodrop-enabled="true">
           <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>
  </div>

and this is my script;

<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>

   <a class="btn btn-xs" data-nodrag>
       <img ng-src="{{node.image}}" class="img-avatar" alt="Avatar" height="35" width="35"></a>
   {{node.title}}


   <div class="dropdown pull-right ">
       <a class="btn btn-primary btn-xs dropdown-toggle" data-toggle="dropdown" data-nodrag><span class="glyphicon glyphicon-th-list"></span></a>
       <div class="dropdown-content dropdown-menu" data-nodrag>
           <a ng-show = "flagCreateUserHierarchy" ng-click="btnAddUserClick(this)"><i class="fa fa-user"></i> Add User</a>
           <a ng-show = "flagUpdateUserHierarchy" ng-click="btnEditClick(this)"><i class="fa fa-folder-open"></i> Edit</a>
           <a ng-show="{{node.type}} <2 && flagUpdateUserHierarchy" ng-click="btnEditGroupClick(this)"><i class="fa fa-folder-open"></i> Edit Group Name</a>
           <a ng-show = "flagUpdateUserHierarchy" ng-click="btnDeleteHierarchy(this)"><i class="fa fa-ban"></i> Delete</a>
       </div>
   </div>

and this is how it looks like...

enter image description here

I can further explain this whole procedure if anyone needs to understand.

Naila Akbar
  • 3,033
  • 4
  • 34
  • 76