2

I have this JSON string that I'm getting through with $.getJSON:

{
    "Menu1":"Item1",
    "Menu2": {
        "SubMenu1":"SubItem1",
        "SubMenu2":"SubItem2"
    },
    "Menu3":"Item3",
    "Menu4": {
        "SubMenu2": {
            "SubSubMenu1":"SubSubItem1"
        }
    }
}

How can I loop through to represent a menu such as:

<ul>
    <li>Item1</li>
    <li>Menu2
        <ul>
            <li>SubItem1</li>
            <li>SubItem2</li>
        </ul>
    </li>
    <li>Item3</li>
    <li>Menu4
        <ul>
            <li>SubMenu2
                <ul>
                    <li>SubSubItem1</li>
                </ul>
            </li>
        </ul>
     </li>
</ul>
4
  • 1
    What's the trouble with your accepted answer to your other question: jQuery JSON looping through nested objects? Commented Dec 18, 2011 at 20:03
  • @RightSaidFred The other answer solves only a part of my question.. I'm trying to get the Key in the <li> in case it's a nested object Commented Dec 18, 2011 at 20:05
  • Did you try on your own? All you need is to change this $("<li>").appendTo(ul) to this $("<li>").append(key).appendTo(ul). jsfiddle.net/uXww2/1 Commented Dec 18, 2011 at 20:09
  • You're welcome. Here's an example using your new data. Commented Dec 18, 2011 at 20:14

3 Answers 3

3

This should do the trick;

function buildNode(key, val) {
  var html="";
  if(typeof val === 'string') {
    html+= '<li>'+val+'</li>';
  }
  else { //assumtion: if it isn't a string it's an object
    html+= '<li>'+key +'<ul>';
    for(var subkey in val) {
      html+= buildNode(subkey, val[subkey]);
    }
    html+= '</ul></li>';
  }
  return html;
}

//assumtion: url serves the json string in question
$.getJSON(url,function(data) {

var html = '<ul>';
for(var key in data) {
  html+= buildNode(key, data[key]);
}
html+='</ul>';

//the variable html now  hold the html you are looking for
});

Note: this could be done more "correctly" by using hasOwnProperty in the loops and do stricter type checking etc. but i will leave that up to the OP :)

Sign up to request clarification or add additional context in comments.

Comments

1

This is what I came up with: http://jsfiddle.net/XE6Nw/

function makeMenu(data) {
    var html = "<ul>";
    $.each(data,function(key,val){
        html += "<li>";
        if (typeof val === "object")
           html +=  key + makeMenu(val);
        else
           html += val;
        html += "</li>";
    });
    html += "</ul>";
    return html;
};

$(makeMenu(data)).appendTo("body");

Insert the above into your $.getJSON() success callback as appropriate. And, obviously, append to the appropriate element - I've just appended to the body for ease of testing in the jsfiddle above.

Comments

1

You don't really need to use jQuery to achieve this. What I'd do is a function and use some recursion (you can test it here: http://jsfiddle.net/ramsvidor/GvR7x/):

function createMenu(items) {
    var menu = document.createElement('ul'),
        i, item;

    for (i in items) {
        if (i != '__proto__' && items[i]) {
            item = document.createElement('li');

            if (typeof(items[i]) === 'object') {
                item.textContent = i;
                item.appendChild(createMenu(items[i]));
            } else {
                item.textContent = items[i];
            }

            menu.appendChild(item);
        }
    }

    return menu;
}

And then you could use jQuery to append to an HTML element.

var menu = { 
    Menu1: 'Item1',
    Menu2: {
        SubMenu1: 'SubItem1',
        SubMenu2: 'SubItem2'
    },
    Menu3: 'Item3',
    Menu4: {
        SubMenu2: {
            SubSubMenu1: 'SubSubItem1'
        }
    }
};

$('#someElement').html(createMenu(menu));

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.