5
\$\begingroup\$

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>

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 30, 2015 at 7:31
\$\endgroup\$
1
  • \$\begingroup\$ I'm looking at doing something similar. Is there a reason you didn't use a nested JSON structure that looks similar to your nested menu structure? That way you wouldn't need to keep track of parentIds and number of children. \$\endgroup\$ Commented Sep 15, 2018 at 3:11

1 Answer 1

3
\$\begingroup\$

At the very least, you should clean up your variables:

  • htmlTxt is declared as var 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 within recurseMenu(). 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>

answered Apr 30, 2015 at 8:03
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.