Create A Nested Ul Menu Based On The Url Path Structure Of Menu Items
Solution 1:
I think the best solution is firstly to convert your data structure to a tree one, with parent/children relations. Render this structure will then be easier, as the UL itself has a tree structure.
You can convert menuItems using these couple of functions
// Add an item node in the tree, at the right positionfunctionaddToTree( node, treeNodes ) {
// Check if the item node should inserted in a subnodefor ( var i=0; i<treeNodes.length; i++ ) {
var treeNode = treeNodes[i];
// "/store/travel".indexOf( '/store/' )if ( node.url.indexOf( treeNode.url + '/' ) == 0 ) {
addToTree( node, treeNode.children );
// Item node was added, we can quitreturn;
}
}
// Item node was not added to a subnode, so it's a sibling of these treeNodes
treeNodes.push({
name: node.name,
url: node.url,
children: []
});
}
//Create the item tree starting from menuItemsfunctioncreateTree( nodes ) {
var tree = [];
for ( var i=0; i<nodes.length; i++ ) {
var node = nodes[i];
addToTree( node, tree );
}
return tree;
}
var menuItemsTree = createTree( menuItems );
console.log( menuItemsTree );
The resulting menuItemsTree will be an object like this
[{"name":"Store","url":"/store","children":[{"name":"Travel","url":"/store/travel","children":[]},{"name":"Gardening","url":"/store/gardening","children":[]},{"name":"Healthy Eating","url":"/store/healthy-eating","children":[{"name":"Cook Books","url":"/store/healthy-eating/cook-books","children":[]},{"name":"Single Meal Gifts","url":"/store/healthy-eating/single-meal-gifts","children":[]}]},{"name":"Outdoor Recreation","url":"/store/outdoor-recreation","children":[{"name":"Hiking","url":"/store/outdoor-recreation/hiking","children":[{"name":"Snowshoeing","url":"/store/outdoor-recreation/hiking/snowshoeing","children":[]}]},{"name":"Skiing","url":"/store/outdoor-recreation/skiing","children":[]}]},{"name":"Physical Fitness","url":"/store/physical-fitness","children":[]},{"name":"Provident Living","url":"/store/provident-living","children":[]}]}]
You mentioned you already have html renderer for trees, right? If you need further help let us know!
Solution 2:
12 simple lines of code:
var rootList = $("<ul>").appendTo("body");
var elements = {};
$.each(menuItems, function() {
var parent = elements[this.url.substr(0, this.url.lastIndexOf("/"))];
var list = parent ? parent.next("ul") : rootList;
if (!list.length) {
list = $("<ul>").insertAfter(parent);
}
var item = $("<li>").appendTo(list);
$("<a>").attr("href", this.url).text(this.name).appendTo(item);
elements[this.url] = item;
});
Solution 3:
Although I like the script of gilly3 the script produces list with different element nesting of <li>
and <ul>
than was originally asked. So instead of
<li><ahref="/store">Store</a><ul><li><ahref="/store/travel">Travel</a></li>
...
</ul></li>
It produces <li><ahref="/store">Store</a></li><ul><li><ahref="/store/travel">Travel</a></li>
...
</ul>
This may cause incompatibilities for utilities or frameworks working with such generated menu and producing interactive menu with animation (e.g. superfish.js).
So I updated the 12 lines script
var rootList = $("<ul>").appendTo("body");
var elements = {};
$.each(menuItems, function() {
var parent = elements[this.url.substr(0, this.url.lastIndexOf("/"))];
var list = parent ? parent.children("ul") : rootList;
if (!list.length) {
list = $("<ul>").appendTo(parent);
}
var item = $("<li>").appendTo(list);
$("<a>").attr("href", this.url).text(this.name).appendTo(item);
elements[this.url] = item;
});
Solution 4:
It's not in jQuery, but maybe this could help. I developed this after seeking the web to do exactly what you want.
Solution 5:
Or maybe complete jQuery plugin http://jsfiddle.net/9FGRC/
(EDIT)
An update to previous version http://jsfiddle.net/9FGRC/1/
This version supports following case
var menuItems = [
{
name : "Store",
url : "/store"
},
{
name : "Cook Books",
url : "/store/healthy-eating/cook-books"
},
{
name : "Single Meal Gifts",
url : "/store/healthy-eating/single-meal-gifts"
}
]
Since there is skipped
{
name : "Healthy Eating",
url : "/store/healthy-eating"
},
It will produce following html
<ul><li><ahref="/store">Store</a><ul><li><ahref="/store/healthy-eating/cook-books">Cook Books</a></li><li><ahref="/store/healthy-eating/single-meal-gifts">Single Meal Gifts</a></li></ul></li></ul>
I guess it won't be the case, but could be helpful to someone
Post a Comment for "Create A Nested Ul Menu Based On The Url Path Structure Of Menu Items"