1

i need to create a tree structure from array of Javascript objects.
I have something like this (not defined children level):

var obj_1 = {id:1, title:"Title 1", parent:0};
var obj_2 = {id:2, title:"Title 1.1", parent:1};
var obj_3 = {id:3, title:"Title 1.2", parent:1};
var obj_4 = {id:4, title:"Title 1.1.1", parent:2};
var obj_5 = {id:5, title:"Title 2", parent:0};

var obj_list = [obj_1,obj_2,obj_3,obj_4,obj_5];

And I need:

var result = [{
               id:1, 
               title:"Title 1", 
               children:[
                        {id:2, title:"Title 1.1", children:[....]}
                        {id:3, title:"Title 1.2"}
                        ]
               },
               {
                ...
               }
              ];

With this structure I want to create HTML list:

<ul>
  <li><a>Title 1</a>
      <ul>
        <li><a>Title 1.1</a>
            <ul>
             <li>Title 1.1.1</li>
            </ul>
        </li>
        <li><a>Title 1.2</a></li>
      </ul>
  </li>
  <li><li><a>Title 2</a></li>
</ul>

Any suggestion to solve this ?
The intermediate structure isn't very important but what I need is the HTML list.

1
  • 2
    This isn't difficult but you ask for very specific code. What's your problem when you try to write it ? Do you have a problem ? Commented Jul 16, 2013 at 13:11

2 Answers 2

2

Converting your objects list into a nested object:

var obj_nested_list = [],
    obj;

function fill_with_children(children_arr, parent_id) {
    // find all objs with parent "parent"
    for (var i = 0; i < obj_list.length; i++) {
        obj = obj_list[i];
        if (obj.parent == parent_id) {
            children_arr.push(obj);
            obj.children = [];
            fill_with_children(obj.children, obj.id);
        }
    }

    children_arr.sort(function(a,b){
        return a.title.downcase == b.title.downcase;
    });
}

fill_with_children(obj_nested_list, 0);

Using the nested object to print nested lists:

function print_list(list, container) {
    for (var i = 0; i < list.length; i++) {
        var li = document.createElement('li');
        li.innerHTML = list[i].title;
        if (list[i].children.length > 0) {
            var ul = document.createElement('ul');
            li.appendChild(ul);
            print_list(list[i].children, ul);
        }
        container.appendChild(li);
    }
}
print_list(obj_nested_list, document.getElementById('list'));

Here's a working example: http://jsfiddle.net/rotev/svFTa/1/

Sign up to request clarification or add additional context in comments.

2 Comments

What should I do to order children by title ?
Use the array.sort() function every time a children array is ready. Edited the answer.
1

The following should do what you need. I suggest learning about recursion, the makeUL function would be a good start.

var obj_1 = {id:1, title:"Title 1", parent:0};
var obj_2 = {id:2, title:"Title 1.1", parent:1};
var obj_3 = {id:3, title:"Title 1.2", parent:1};
var obj_4 = {id:4, title:"Title 1.1.1", parent:2};
var obj_5 = {id:5, title:"Title 2", parent:0};
// make an object keyed by the ID
var root = {};
var cnt = 1;
try { obj = eval("obj_" + cnt); } catch(err) { obj = null; }
while(obj) {
    obj.children = [];
    root[obj.id] = obj;
    try { obj = eval("obj_" + (++cnt)); } catch(err) { break; }
}
// make the object treeified list
var list = []
for(var k in root) {
    var node = root[k];
    if(node.parent != 0) {
        root[node.parent].children.push(node);
    } else {
        list.push(node);
    }
}
// make HTML UL
function makeUL(list, result) {
    for(var i=0; i<list.length; i++) {
        var node = list[i];
        var li = result.appendChild(document.createElement("li"));
        var a = li.appendChild(document.createElement("a"));
        a.innerHTML = node.title;
        if(node.children.length > 0) {
            makeUL(node.children, li.appendChild(document.createElement("ul")));
        }
    }
    return result;
}
var result = makeUL(list, document.createElement("ul")); 
console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.