Problem
I have a JSON input using which I have written below function to recursively create an unordered list.
Is there more precise way to achieve it?
$(document).ready(function () {
var htmlTxt = "";
var cat = [];
var htmlStrTxt = "";
var url = "#";
function recurseMenu(parent, level) {
htmlStrTxt = '<ul>';
for (var x in menuItems) {
if (menuItems[x].parentId == parent) {
htmlStrTxt += '<li><img/><a href="' + url + '">' + menuItems[x].title + '</a>';
if (menuItems[x].childCount > 0) {
htmlStrTxt += recurseMenu(menuItems[x].id, level + 1);
}
htmlStrTxt += '</li>';
}
}
return htmlStrTxt + '</ul>';
}
var htmlTxt = recurseMenu(null, 0);
$("#listContainer").html(htmlTxt);
});
<!-- Test case -->
<div id="listContainer"></div>
<script>
var menuItems = {
"menu-0": {
"id": "menu-0",
"title": "Home",
"parentId": null,
"childCount": 0
},
"menu-1": {
"id": "menu-1",
"title": "About",
"parentId": null,
"childCount": 2
},
"menu-3": {
"id": "menu-3",
"title": "About Sub1",
"parentId": "menu-1",
"childCount": 2
},
"menu-5": {
"id": "menu-5",
"title": "About Sub2",
"parentId": "menu-1",
"childCount": 0
},
"menu-4": {
"id": "menu-4",
"title": "About Sub1 sub1",
"parentId": "menu-3",
"childCount": 0
},
"menu-6": {
"id": "menu-6",
"title": "Contact",
"parentId": null,
"childCount": 2
},
"menu-7": {
"id": "menu-7",
"title": "Contact sub1",
"parentId": "menu-6",
"childCount": 0
},
"menu-8": {
"id": "menu-8",
"title": "Contact sub2",
"parentId": "menu-6",
"childCount": 1
},
"menu-9": {
"id": "menu-9",
"title": "Contact sub2 sub1",
"parentId": "menu-8",
"childCount": 0
},
"menu-10": {
"id": "menu-10",
"title": "About Sub1 sub2",
"parentId": "menu-3",
"childCount": 2
},
"menu-11": {
"id": "menu-11",
"title": "About Sub1 sub2 sub1",
"parentId": "menu-10",
"childCount": 0
} ,
"menu-12": {
"id": "menu-11",
"title": "About Sub1 sub2 sub2",
"parentId": "menu-10",
"childCount": 0
}
};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Solution
At the very least, you should clean up your variables:
htmlTxt
is declared asvar
twice in the same scope. I don’t think you even need it at all.cat
is never used.htmlStrTxt
would be better as a local function withinrecurseMenu()
. A shorter variable name would do just as well.- The
level
parameter is useless.
$(document).ready(function () {
var url = "#";
function recurseMenu(parent) {
var s = '<ul>';
for (var x in menuItems) {
if (menuItems[x].parentId == parent) {
s += '<li><img/><a href="' + url + '">' + menuItems[x].title + '</a>';
if (menuItems[x].childCount > 0) {
s += recurseMenu(menuItems[x].id);
}
s += '</li>';
}
}
return s + '</ul>';
}
$("#listContainer").html(recurseMenu());
});
<!-- Test case -->
<div id="listContainer"></div>
<script>
var menuItems = {
"menu-0": {
"id": "menu-0",
"title": "Home",
"parentId": null,
"childCount": 0
},
"menu-1": {
"id": "menu-1",
"title": "About",
"parentId": null,
"childCount": 2
},
"menu-3": {
"id": "menu-3",
"title": "About Sub1",
"parentId": "menu-1",
"childCount": 2
},
"menu-5": {
"id": "menu-5",
"title": "About Sub2",
"parentId": "menu-1",
"childCount": 0
},
"menu-4": {
"id": "menu-4",
"title": "About Sub1 sub1",
"parentId": "menu-3",
"childCount": 0
},
"menu-6": {
"id": "menu-6",
"title": "Contact",
"parentId": null,
"childCount": 2
},
"menu-7": {
"id": "menu-7",
"title": "Contact sub1",
"parentId": "menu-6",
"childCount": 0
},
"menu-8": {
"id": "menu-8",
"title": "Contact sub2",
"parentId": "menu-6",
"childCount": 1
},
"menu-9": {
"id": "menu-9",
"title": "Contact sub2 sub1",
"parentId": "menu-8",
"childCount": 0
},
"menu-10": {
"id": "menu-10",
"title": "About Sub1 sub2",
"parentId": "menu-3",
"childCount": 2
},
"menu-11": {
"id": "menu-11",
"title": "About Sub1 sub2 sub1",
"parentId": "menu-10",
"childCount": 0
} ,
"menu-12": {
"id": "menu-11",
"title": "About Sub1 sub2 sub2",
"parentId": "menu-10",
"childCount": 0
}
};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>