timkit
timkit

Reputation: 47

Make tree from object

Object:

    var src = {
    0: {child: [1], title: "Books"},
    1: {child: [2,3], title: "Programming"},
    2: {title: "Languages"},
    3: {child: [4,5],title: "Databases"},
    4: {title: "MongoDB"},
    5: {title: "dbm"}
};

How can you build a tree in the form of this object

<div id="tree">
    <ul>
        <li id="0">
            <span>Books</span>
            <ul>
                <li id="1">
                    <span>Programming</span>
                    <ul>
                        <li id="2">
                            <span>Languages</span>
                        </li>
                        <li id="3">
                            <span>Databases</span>
                            <ul>
                                <li id="4">
                                    <span>MongoDB</span>
                                </li>
                                <li id="5">
                                    <span>dbm</span>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

To simplify the structure of the tree is changed, but the essence remains. Please tell me.

I tried, but with different data structure

var data = {
    0: {title: "Books"},
    1: {pid: 0, title: "Programming"},
    2: {pid: 1, title: "Languages", ch: 0},
    3: {pid: 1, title: "Databases"},
    4: {pid: 3, title: "MongoDB", ch: 0},
    5: {pid: 3, title: "dmb", ch: 0}
};          
    function makeTree(data) {
    var child = [];
    var i = 0;
    for (var key in data) {
        if (data[key].hasOwnProperty('pid')) {
            if (data[key].hasOwnProperty('ch')) {
                child[i] = document.createElement('li');
                child[i].setAttribute('id', key);
                child[i].innerHTML = data[key].title + ' <span></span></li>';
            }
            else {
                child[i] = document.createElement('li');
                child[i].setAttribute('id', key);
                child[i].innerHTML = data[key].title + '<span></span>';
                child[i].innerHTML += '<ol><li id=' + key + '>' + data[key].title + '<span></span></li></ol>';
            }
            document.getElementById(data[key].pid + "").appendChild(child[i]);
            i++;
        }
        else {
            var li = document.createElement('li');
            li.setAttribute('id', key);
            li.innerHTML = data[key].title + '<span></span>'
            tree.appendChild(li);
        }
    }
}

It works, but not correctly

Upvotes: 2

Views: 146

Answers (2)

Andrei
Andrei

Reputation: 3106

You can do it like this. It generates HTML like you wanted. It iterates recursively from parent to children.

var outputHtml = '<div id="tree">';
function buildTree(parrent)
{
    var currentParent = parrent;
     outputHtml += '<ul>';
     if(parrent === -1)
     {
         outputHtml += '<li id="' + 0 + '">';
         outputHtml += '<span>'+ src[0].title +'</span>';
         buildTree(0);
         outputHtml += '</li>';
     }
    else{
         for(var i = 0, childArray = src[currentParent].child, iLength = childArray.length; i < iLength; ++i)
         {
             outputHtml += '<li id="' + childArray[i]+ '">';
             outputHtml += '<span>'+ src[childArray[i]].title +'</span>';
             if(src[childArray[i]].child)
                 buildTree(childArray[i]);
             outputHtml += '</li>';
         }
    }

     outputHtml += '</ul>';
}
buildTree(-1);
outputHtml += '</div>';
  • Add the opening div
  • Check if it is root and add it, than call buildTree to print children.
  • For each child of the parent, print it.
  • If it has children, call buildTree to print them too.
  • Add the ending div.

As you can see it works ok here:

http://jsfiddle.net/ALUVu/1/

Upvotes: 1

sjkm
sjkm

Reputation: 3937

You can do that by doing something like this (I used plain javascript since you didn't tag the question with jquery or whatever):

var src = {
    0: {child: [1], title: "Books"},
    1: {child: [2,3], title: "Programming"},
    2: {title: "Languages"},
    3: {child: [4,5],title: "Databases"},
    4: {title: "MongoDB"},
    5: {title: "dbm"}
};

var rootNodes = [];

// create dom elements
var domElements = [];
for(var prop in src) {
    var ul = document.createElement('ul');
    var li = document.createElement('li');
    var span = document.createElement('span');
    span.innerHTML = src[prop].title;
    li.appendChild(span);
    ul.appendChild(li);
    domElements[domElements.length] = ul;
}

// nest elements
for(var i = 0; i < domElements.length; i++) {
    var domElement = domElements[i];
    var dataItem = src[i];
    var children = dataItem.child;
    if(children) {
        for(var j = 0; j < children.length; j++) {
            var childDomElement = domElements[children[j]];
            domElement.firstChild.appendChild(childDomElement);
        }
    } else {
        rootNodes[rootNodes.length] = domElement;
    }
}

// output rootNodes
console.log(rootNodes); // gives the desired output

Upvotes: 1

Related Questions