Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all the parents of each element

I'm trying to create a breadcrumb without using the url (the route provider) and without using jQuery. I have a tree like that

Humans
Trees
Animals
    Cats
    Lions
    Dogs
       Terrier 
       Bulldog
       Cocker
Cars

and I'd like when I click on Cocker to display

Animals / Dogs / Cocker

So, I created a recursive function in order to find parent/parents for each element that I click on but it doesn't work correctly. It finds that an element has a parent, it also finds the first parent of an element but it doesn't show the second parent. For instance instead of

Animals / Dogs / Cocker

it shows

Dogs / Cocker

That's my function

var count = 0;
function iterate(obj) {
    for(var key in obj) {
      var elem = obj[key];
      if(key === "children") {
        count++;
      }
      if(typeof elem === "object") {
        if(elem.children === undefined){
          elem.children = 1;
        }
        if(elem.children.length !==1){
          iterate(elem);
          $scope.showTrail = elem.children;
          $scope.elem = elem;
        }
      }
     }
    if($scope.elem === undefined){
      $scope.elem = {};
      $scope.elem.children = {};
      $scope.elem.roleName = {};
    }

    for (var i = 0; i<$scope.elem.children.length; i++) {
       if($scope.elem.children[i].roleName === selNode.roleName) {
          console.log($scope.elem.roleName + " is a parent of " + selNode.roleName);
       }
    }

  }
iterate($scope.treeData);

and that's the JSON

     [
          { "roleName" : "Humans", "roleId" : "role2", "children" : [
           { "roleName" : "", "roleId" : "role11", "children" : [] }
          ]},
          { "roleName" : "Trees", "roleId" : "role2", "children" : [
           { "roleName" : "", "roleId" : "role11", "children" : [] }
          ]},
          { "roleName" : "Animals", "roleId" : "role2", "children" : [
            { "roleName" : "Cats", "roleId" : "role11", "children" : [
             { "roleName" : "", "roleId" : "role11", "children" : [] }
            ]},
            { "roleName" : "Lions", "roleId" : "role11", "children" : [
             { "roleName" : "", "roleId" : "role11", "children" : [] }
            ]},
            { "roleName" : "Dogs", "roleId" : "role11", "children" : [
              { "roleName" : "Terrier", "roleId" : "role11", "children" : [
               { "roleName" : "", "roleId" : "role11", "children" : [] }
              ]},
              { "roleName" : "Bulldog", "roleId" : "role11", "children" : [
               { "roleName" : "", "roleId" : "role11", "children" : [] }
              ]},
              { "roleName" : "Cocker", "roleId" : "role11", "children" : [
               { "roleName" : "", "roleId" : "role11", "children" : [] }
              ]},
            ]}
          ]},
          { "roleName" : "Cars", "roleId" : "role2", "children" : [
           { "roleName" : "", "roleId" : "role11", "children" : [] }
          ]}
     ]

Any help please, any idea. Thank you very much.

like image 667
jimakos17 Avatar asked Feb 15 '23 15:02

jimakos17


2 Answers

You are iterating over the tree, but it won't help if you don't keep some information. The simplest solution to your problem is to build an index of all nodes that points to their parents.

This code will work if roleName has unique values across the whole tree:

var tree = [
    { "roleName" : "Humans", "roleId" : "role2", "children" : []},
    { "roleName" : "Trees", "roleId" : "role2", "children" : []},
    { "roleName" : "Animals", "roleId" : "role2", "children" : [
        { "roleName" : "Cats", "roleId" : "role11", "children" : []},
        { "roleName" : "Lions", "roleId" : "role11", "children" : []},
        { "roleName" : "Dogs", "roleId" : "role11", "children" : [
            { "roleName" : "Terrier", "roleId" : "role11", "children" : []},
            { "roleName" : "Bulldog", "roleId" : "role11", "children" : []},
            { "roleName" : "Cocker", "roleId" : "role11", "children" : []},
        ]}
    ]},
    { "roleName" : "Cars", "roleId" : "role2", "children" : []}
];

var index = {};

function buildIndex(root, children) {
    for(var i in children) {
        index[children[i].roleName] = root;
        buildIndex(children[i].roleName, children[i].children);
    }
}

buildIndex("Root", tree);

function getPath(leaf) {
    return index[leaf] ? getPath(index[leaf]).concat([leaf]) : [leaf];
}

getPath("Bulldog");// returns ["Root", "Animals", "Dogs", "Bulldog"]

JSFiddle: http://jsfiddle.net/E49Ey/

However it has nothing to do with Angular, except the data resides in the scope. If you have a DOM tree built from this data, then you could get the breadcrumb right from the DOM by going up the tree.

like image 137
Adam Avatar answered Feb 28 '23 07:02

Adam


Hey I put together a quick plunkr doing what your looking for... except it doesn't reverse-traverse up the data tree.

http://embed.plnkr.co/wAJYiAjy58vUEsg4Kr2C

If your looking to actually looking to run up the data tree let me know and I'll modify the plunkr

like image 21
anthony.c Avatar answered Feb 28 '23 07:02

anthony.c