Q:

Multi level nested menu from json

How do I create a nested menu (with "sub-sub-sub...-n") items from my JSON, based on the "id" and the "pid"?
Code details:
id - item ID
lvl - level of the item
pid - parent ID of the item
pos - position of the item
nm - name of the item

JSON:
[{"id":1,"lvl":0,"pid":0,"pos":0,"nm":"HomeTree"},
{"id":5,"lvl":1,"pid":1,"pos":0,"nm":"Books"},
{"id":2,"lvl":1,"pid":1,"pos":1,"nm":"Jobs"},
{"id":16,"lvl":1,"pid":1,"pos":2,"nm":"Music"},
{"id":17,"lvl":2,"pid":16,"pos":0,"nm":"Relax Sets"},
{"id":12,"lvl":1,"pid":1,"pos":3,"nm":"Cars"},
{"id":13,"lvl":2,"pid":12,"pos":0,"nm":"BMW"},
{"id":14,"lvl":1,"pid":1,"pos":4,"nm":"Web"},
{"id":15,"lvl":2,"pid":14,"pos":0,"nm":"PHP Analytics"},
{"id":18,"lvl":1,"pid":1,"pos":5,"nm":"Hardware"},
{"id":19,"lvl":2,"pid":18,"pos":0,"nm":"EVGA SR2 Upgrades"},
{"id":31,"lvl":2,"pid":18,"pos":1,"nm":"Keyboards"},
{"id":20,"lvl":1,"pid":1,"pos":6,"nm":"Movies"},
{"id":21,"lvl":1,"pid":1,"pos":7,"nm":"Games"},
{"id":22,"lvl":1,"pid":1,"pos":8,"nm":"Robots"},
{"id":25,"lvl":1,"pid":1,"pos":9,"nm":"Magazines"},
{"id":26,"lvl":2,"pid":25,"pos":0,"nm":"IT Security"},
{"id":27,"lvl":1,"pid":1,"pos":10,"nm":"Management"},
{"id":28,"lvl":2,"pid":27,"pos":0,"nm":"Holacracy"},
{"id":29,"lvl":3,"pid":28,"pos":0,"nm":"Testtt"}]

What I need:
HomeTree
    Books
    Jobs
    Music
    Relax Sets
    Cars
        BMW
    Web
        PHP Analytics
    Hardware
        EVGA SR2 Upgrades
    Keyboards
    Movies
    Games
    Robots
    Magazines
        IT Security
    Management
        Holacracy
            Testtt

My current code:
$.ajax({
    url: './jstree_head.php?operation=full_tree',
    data: "",
    dataType: 'json',
    success: function(data)
    {
        var output="<br />";
        for (var i in data)
        {
                var rid = data[i].id;
                var rpid = data[i].pid;
                var rlvl = data[i].lvl;
                var rnm = data[i].nm;

                var nest = '&nbsp; &nbsp; &nbsp;';
                if(rpid > 1) {
                                 nm = nest+rnm+'<br>';
                             }
                else {nm = rnm+'<br>';}

            output+='' + nm + '';
        }
        $('#content').html(output);
    }
});

Right now I can't account for deep sub-sub levels, what is the right way to do that?
--- UPDATE ---
What I tried is:
var nest = '&nbsp; &nbsp; &nbsp;';
if(rpid > 1) {
    nm = nest+rnm+'<br>';
}
else {nm = rnm+'<br>';}

output+='' + nm + '';

But this does only one level of parent items.

A:

Since your output is not formatted, I am first creating a hierarchy of parent-child which is then being used to print the output. Instead of directly storing the values in string, I am using JSON as it's much easier to dynamically add child there.
var data = [{"id":1,"lvl":0,"pid":0,"pos":0,"nm":"HomeTree"},
    {"id":5,"lvl":1,"pid":1,"pos":0,"nm":"Books"},
    {"id":2,"lvl":1,"pid":1,"pos":1,"nm":"Jobs"},
    {"id":16,"lvl":1,"pid":1,"pos":2,"nm":"Music"},
    {"id":17,"lvl":2,"pid":16,"pos":0,"nm":"Relax Sets"},
    {"id":12,"lvl":1,"pid":1,"pos":3,"nm":"Cars"},
    {"id":13,"lvl":2,"pid":12,"pos":0,"nm":"BMW"},
    {"id":14,"lvl":1,"pid":1,"pos":4,"nm":"Web"},
    {"id":15,"lvl":2,"pid":14,"pos":0,"nm":"PHP Analytics"},
    {"id":18,"lvl":1,"pid":1,"pos":5,"nm":"Hardware"},
    {"id":19,"lvl":2,"pid":18,"pos":0,"nm":"EVGA SR2 Upgrades"},
    {"id":31,"lvl":2,"pid":18,"pos":1,"nm":"Keyboards"},
    {"id":20,"lvl":1,"pid":1,"pos":6,"nm":"Movies"},
    {"id":21,"lvl":1,"pid":1,"pos":7,"nm":"Games"},
    {"id":22,"lvl":1,"pid":1,"pos":8,"nm":"Robots"},
    {"id":25,"lvl":1,"pid":1,"pos":9,"nm":"Magazines"},
    {"id":26,"lvl":2,"pid":25,"pos":0,"nm":"IT Security"},
    {"id":27,"lvl":1,"pid":1,"pos":10,"nm":"Management"},
    {"id":28,"lvl":2,"pid":27,"pos":0,"nm":"Holacracy"},
    {"id":29,"lvl":3,"pid":28,"pos":0,"nm":"Testtt"}];

var output="<br />";

var res = [];
function createRelationship(){
    for (var i in data)
    {
        if(data[i].pid == 0 && data[i].id == 1){
            res.push({
            id: data[i].id,
            nm: data[i].nm
            });
        }
        else{
            var parent = findParent(data[i].pid, res);
            if(parent){
                if(!parent.items){
                    parent.items = [];
                }
                parent.items.push({
                    id: data[i].id,
                    nm: data[i].nm
                });
            }
        }
    }
}

function findParent(pid, _res){
    if(_res){
        if(_res.id == pid){
            return _res;
        }
        var len = _res.length ? _res.length : _res.items ? _res.items.length : 0;
        for(var i =0; i< len; i++){
            if(_res[i] && _res[i].id == pid){
                return _res[i];
            }
            else{
                var child = _res[i] ? _res[i] : _res;
                if(child){
                    for(var j=0;j<child.items.length;j++){
                        var res = findParent(pid, child.items[j]);
                        if(res){
                            return res;
                        }
                    }
                }
            }
        }
    }
    return null;
}

function printOutPut(obj, spaceCount){
    var space = '';
    for(var i = 0; i< spaceCount; i++){
        space+= '&nbsp;';
    }
    output += space + obj.nm;
    output += "<br />";
    if(obj.items){
        for(i = 0; i < obj.items.length; i++){
            printOutPut(obj.items[i], (spaceCount + 4));
        }
    }
}

createRelationship();

for(var z =0; z<res.length;z++){
    printOutPut(res[z], 1);
}

document.write(output); 

