1

I have the below unordered list

<ul>
    <li data-id="111" data-sub="0" data-url="home" data-active="1">Home</li>
    <li data-id="222" data-sub="0" data-url="about" data-active="1">About</li>
    <li data-id="333" data-sub="1" data-url="news" data-active="1">News
        <ul>
            <li data-id="444" data-sub="0" data-url="news/latest" data-active="1">Latest</li>
            <li data-id="555" data-sub="0" data-url="news/reports" data-active="1">Reports</li>
        </ul>
    </li>
</ul>

I want to get the data attributes and output it in JSON so that it appears in the same format as below

[{
    "active": 1,
    "url": "home",
    "sub": 0,
    "id": 111
}, {
    "active": 1,
    "url": "about",
    "sub": 0,
    "id": 222
}, {
    "active": 1,
    "url": "news",
    "sub": 1,
    "id": 333,
    "child": [{
        "active": 1,
        "url": "news/latest",
        "sub": 0,
        "id": 444
    }, {
        "active": 1,
        "url": "news/reports",
        "sub": 0,
        "id": 555
    }]
}]

Currently I have the below JS

<script>
    var mynav = [];
    $("li").each(function () {
          if($(this).children("ul").length) {
              $(this).data('child', '"' + $(this).data() + '"');
              mynav.push($(this).data());
       }
        mynav.push($(this).data());
    });
    mynav = JSON.stringify(mynav);
    console.log(mynav);
</script>

Which outputs the below.

[{
    "active": 1,
    "url": "home",
    "sub": 0,
    "id": 111
}, {
    "active": 1,
    "url": "about",
    "sub": 0,
    "id": 222
}, {
    "active": 1,
    "url": "news",
    "sub": 1,
    "id": 333,
    "child": "\"[object Object]\""
}, {
    "active": 1,
    "url": "news",
    "sub": 1,
    "id": 333,
    "child": "\"[object Object]\""
}, {
    "active": 1,
    "url": "news/latest",
    "sub": 0,
    "id": 444
}, {
    "active": 1,
    "url": "news/reports",
    "sub": 0,
    "id": 555
}]

My format is fine for a simple un ordered list by when a list item has additional sum items like my example I am not able to convert my list to the correct JSON format. What do I need to do to my JS to get it to format the sub lists the way I want them as well?

1
  • 3
    you need to take one child array to push the child value and push that child array to parent array. Commented Aug 20, 2014 at 4:15

3 Answers 3

4

You can give an id to the top element like

<ul id="mynav">
    <li data-id="111" data-sub="0" data-url="home" data-active="1">Home</li>
    <li data-id="222" data-sub="0" data-url="about" data-active="1">About</li>
    <li data-id="333" data-sub="1" data-url="news" data-active="1">News
        <ul>
            <li data-id="444" data-sub="0" data-url="news/latest" data-active="1">Latest</li>
            <li data-id="555" data-sub="0" data-url="news/reports" data-active="1">Reports</li>
        </ul>
    </li>
</ul>

then

var nav = getNav($('#mynav'));

function getNav($ul) {
    return $ul.children('li').map(function () {
        var $this = $(this),
            obj = $this.data(),
            $ul = $this.children('ul');
        if ($ul.length) {
            obj.child = getNav($ul)
        }
        return obj;
    }).get()
}

Demo: Fiddle

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

Comments

3

Here's one way to do it

var nav = (function rec(el) {
    return el.map(function() {
        var o = $(this).data(),
            c = $(this).children('ul').children('li');

        if ( c.length > 0 ) o.child = rec(c);
        return o
    }).get();
})($(' body > ul > li'));

recursively traversing the children and building the JSON

FIDDLE

Comments

1

The way you want to do this: DEMO

var mynav = [];
    $("#ulid").children("li").each(function () {
        var that = this;
          if($(that).children("ul").length) {
              var temp = [];/*I am CHILD array*/
              $(that).children("ul").find("li").each(function(){
                  temp.push($(this).data());
              });
              $(that).data().child = temp;
       }
        mynav.push($(that).data());
    });
    mynav = JSON.stringify(mynav, null, 4);
$('body').html('<pre>' + mynav + '</pre>');

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.