JSFiddle - React, Tailwind, and code Playground
HTML
<menu id="main_menu">
</menu>
CSS
ul {
list-style: disc;
padding-left: 20px;
}
JavaScript
// usage is at the bottom
(function($) {
$.fn.myMenu = function(opt) {
var _regex = /(\/[\w-_]+)/g;
var _this = $(this);
var _map = {};
function addToMap(item){
var paths = item.url.match(_regex);
var temp = {};
var branch = temp;
for(var i=0; i< paths.length; i++){
temp[paths[i]] = { children: {} };
if( i == paths.length -1){
temp[paths[i]].name = item.name;
}
temp = temp[paths[i]].children;
}
$.extend(true,_map, branch);
}
for(var item in opt){
addToMap(opt[item]);
}
//map ready
console.log(_map);
var menu = [];
function createHTML(item, current_path){
var result = "";
if (item.hasOwnProperty("children")){
for(var path in item.children){
if(path.match("^\\/")){
// starts with
result += createHTML(item.children[path], current_path + path);
}
}
if(result.length > 0 && item.hasOwnProperty("name")){
// we want to wrap as submenu only if current node has NAME otherwise
// return as list of <li> tags it woill be wrapped in parent witn NAME property
result = "<ul>" + result + "</ul>";
}
}
if(item.hasOwnProperty("name")){
result = "<li><a href='"+current_path+"'>" + item.name + "</a>" + result + "</li>";
}
return result;
}
menu.push("<ul style='border:1px solid #000'>");
for(var node in _map){
if(node.match("^\\/")){ // starts with
menu.push(createHTML(_map[node], node));
}
}
...