I\'m trying to create a nested UL from JSON. I am able to loop through and grab the data from the object, but I am having trouble building the nested UL. I figure the \'.app
You can use a recursive function for appending submenus.
This is a simple solution for three sublevels or more
function appendMeu(parent, menu, level) {
for(var i = 0;i < menu.length; i ++) {
var submenu = parent.append('<li>' + menu[i].title + '</li>')
.find("li:last");
if(menu[i].menu != undefined && menu[i].menu.length > 0) {
submenu = submenu.append('<ul class="submenuLevel' + (level + 1) + '"></ul>').find("ul");
appendMeu(submenu, menu[i].menu, level + 1);
}
}
}
$(function() {
appendMeu($(".mainMenu"), menu, 0);
});
Here's how to do this with the jQuery template plugin I mentioned
This would be in your script tag:
$(function () {
$('#t_menu').tmpl(menu).appendTo('#test');
});
And this in your html :
<div id="test"> </div>
<script id="t_menu" type="text/html">
<ul class="mainMenu">
{{each menu}}
<li class="main">
<a href="${url}">${title}</a>
<ul class="submenuLevel1">
{{each menu}}
<li class="level1">
<a href="${url}">${title}</a>
<ul class="submenuLevel2">
{{each menu}}
<li class="level2">
<a href="${url}">${title}</a>
</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</script>
Here's a nicer solution:
var Menu = function(data) {
this.data = data;
};
Menu.prototype.render = function(root) {
var ul = $("<ul></ul>");
var li = $("<li></li>");
li.append($("<a></a>", {
href: this.data.url,
text: this.data.title
})).appendTo(ul);
ul.appendTo(root);
if (this.data.menu) {
Menu.renderMenus(this.data.menu, $("<li></li>").appendTo(ul));
}
};
Menu.renderMenus = function(menus, root) {
$.each(menus, function(key, val) {
var m = new Menu(val);
m.render(root);
});
}
Menu.renderMenus(menu, $("#container"));
Live example
Most of what you make is dynamic so start with something like this
<div id="test">
<ul class="mainMenu">
</ul>
</div>
Then in your code use the things you just made and add to them. Something like this:
for(var i = 0; i < menu.length; i++){
var navItem = menu[i];
subMenuL1 = mainMenu.append('<li class="main"><a href="' + navItem.url + '">' + navItem.title +' </a></li>');
for(var j = 0; j < menu[i].menu.length; j++){
var navItemLevel1 = navItem.menu[j];
subMenuL2 = subMenuL1.append('<li class="level1"><a href="' + navItemLevel1.url + '">' + navItemLevel1.title +' </a></li>');
for(var k = 0; k < menu[i].menu[j].menu.length; k++){
var navItemLevel2 = navItemLevel1.menu[k];
subMenuL2.append('<li class="level2"><a href="' + navItemLevel2.url + '">' + navItemLevel2.title +' </a></li>');
}
}
};
Note: I did not test at all... just looked at the example code and made a few changes to get you in the right direction.
Here is a solution:
var mainMenu = $("#test ul.mainMenu");
var i, j, k, navItem, navItemLevel1, navItemLevel2;
for(var i = 0; i < menu.length; i++){
var navItem = menu[i];
var new_li = $('<li class="main"><a href="' + navItem.url + '">' + navItem.title +' </a></li>');
mainMenu.append(new_li);
for(var j = 0; j < menu[i].menu.length; j++){
var new_li_ul = $('ul.submenuLevel1', new_li);
if(new_li_ul.length <= 0){
new_li_ul = $('<ul class="submenuLevel1"></ul>');
new_li.append(new_li_ul);
}
var navItemLevel1 = navItem.menu[j];
var new_li_li = $('<li class="level1"><a href="' + navItemLevel1.url + '">' + navItemLevel1.title +' </a></li>');
new_li_ul.append(new_li_li);
for(var k = 0; k < menu[i].menu[j].menu.length; k++){
var new_li_ul_ul = $('ul.submenuLevel2', new_li_li);
if(new_li_ul_ul.length <= 0){
new_li_ul_ul = $('<ul class="submenuLevel2"></ul>');
new_li_li.append(new_li_ul_ul);
}
var navItemLevel2 = navItemLevel1.menu[k];
new_li_ul_ul.append('<li class="level2"><a href="' + navItemLevel2.url + '">' + navItemLevel2.title +' </a></li>');
}
}
};
Here is a fiddle: http://jsfiddle.net/maniator/6JnuG/3/