I have this JSON string that I'm getting through with $.getJSON:
{
"Menu1":"Item1",
"Menu2": {
"SubMenu1":"SubItem1",
"SubMenu2":"SubItem2"
},
"Menu3":"Item3",
"Menu4": {
"SubMenu2": {
"SubSubMenu1":"SubSubItem1"
}
}
}
How can I loop through to represent a menu such as:
<ul>
<li>Item1</li>
<li>Menu2
<ul>
<li>SubItem1</li>
<li>SubItem2</li>
</ul>
</li>
<li>Item3</li>
<li>Menu4
<ul>
<li>SubMenu2
<ul>
<li>SubSubItem1</li>
</ul>
</li>
</ul>
</li>
</ul>
3 Answers 3
This should do the trick;
function buildNode(key, val) {
var html="";
if(typeof val === 'string') {
html+= '<li>'+val+'</li>';
}
else { //assumtion: if it isn't a string it's an object
html+= '<li>'+key +'<ul>';
for(var subkey in val) {
html+= buildNode(subkey, val[subkey]);
}
html+= '</ul></li>';
}
return html;
}
//assumtion: url serves the json string in question
$.getJSON(url,function(data) {
var html = '<ul>';
for(var key in data) {
html+= buildNode(key, data[key]);
}
html+='</ul>';
//the variable html now hold the html you are looking for
});
Note: this could be done more "correctly" by using hasOwnProperty in the loops and do stricter type checking etc. but i will leave that up to the OP :)
Comments
This is what I came up with: http://jsfiddle.net/XE6Nw/
function makeMenu(data) {
var html = "<ul>";
$.each(data,function(key,val){
html += "<li>";
if (typeof val === "object")
html += key + makeMenu(val);
else
html += val;
html += "</li>";
});
html += "</ul>";
return html;
};
$(makeMenu(data)).appendTo("body");
Insert the above into your $.getJSON() success callback as appropriate. And, obviously, append to the appropriate element - I've just appended to the body for ease of testing in the jsfiddle above.
Comments
You don't really need to use jQuery to achieve this. What I'd do is a function and use some recursion (you can test it here: http://jsfiddle.net/ramsvidor/GvR7x/):
function createMenu(items) {
var menu = document.createElement('ul'),
i, item;
for (i in items) {
if (i != '__proto__' && items[i]) {
item = document.createElement('li');
if (typeof(items[i]) === 'object') {
item.textContent = i;
item.appendChild(createMenu(items[i]));
} else {
item.textContent = items[i];
}
menu.appendChild(item);
}
}
return menu;
}
And then you could use jQuery to append to an HTML element.
var menu = {
Menu1: 'Item1',
Menu2: {
SubMenu1: 'SubItem1',
SubMenu2: 'SubItem2'
},
Menu3: 'Item3',
Menu4: {
SubMenu2: {
SubSubMenu1: 'SubSubItem1'
}
}
};
$('#someElement').html(createMenu(menu));
$("<li>").appendTo(ul)to this$("<li>").append(key).appendTo(ul). jsfiddle.net/uXww2/1