开发者

How to generate nested json object from nested list with javascript/jquery

I would like to generate the following object:

var ideaBoard = {
     "Staff Retreat" : {
         "Games" : [
             {"title" : "Rockband", "details" : "1hr"},
             {"title" : "Texas Hold em", "details" : "30min"}
         ],
         "Talks" : [
             {"title" : "The Old You", "details" : "Dr. Smith"}
         ]
     }
}

from the following HTML:

<div id="data">
    <ul><span class="board-title">Staff Retreat</span>
        <li><span class="category-title">Games</span>
            <ul>
                <li>
                    <span class="title">Rockband</span>
                    <span class="details">1hr</span>
                </li>
                <li>
                    <span class="title">Texas Hold em</span>
                    <span class="details">30min</span>
                </li>
            </ul>
        </li>
        <li><span class="category-title">Talks</span>
            <ul>
                <li>
                    <span class="title">The Old You</span>
                    <span class="details">Dr. Smith</开发者_开发知识库span>
                </li>
            </ul>
        </li>
    </ul>
</div>

I'm new to loops/arrays/objects - so I really appreciate the help!

I'm using jQuery elsewhere in this project, if it helps.

Thanks!


There a multiple ways. Here is one:

var ideaBoard = {}
$('#data > ul').each(function() {
   var data = {}, // board data
       title = $(this).find('.board-title').text(); // board title

   // find categories
   $(this).find('> li > .category-title').each(function() {
        var category = $(this).text(), // category title

        // we can use map to create the array
        var category_data = $(this).next().children('li').map(function() {
            var tdata = {};

            // each span contains detailed data
            $(this).children('span').each(function() {
                tdata[this.className] = $(this).text();
            });

            return tdata;
        }).get();

        data[category] = category_data;
   });

  ideaBoard[title] = data;
});

DEMO

This will most likely break if you change the structure of the HTML. If you have a lot of data like this, this code might also be quite slow.

To learn about the methods used, have a look at the jQuery documentation.


It is not optimized, but it works:

var result = {};
var node1;
var node2;
var node3;
var tmpObj = {};
$('#data > ul').each(function() {
    node1 = $(this);
    result[node1.find('.board-title').text()] = {};
    node1.find('.category-title').each(function() {
        node2 = $(this);
        result[node1.find('.board-title').text()][node2.text()] = [];
        node2.next('ul').children('li').each(function() {
            node3 = $(this);
            tmpObj = {};
            node3.children('span').each(function() {
                tmpObj[$(this).attr('class')] = $(this).text();
            });
            result[node1.find('.board-title').text()][node2.text()].push(tmpObj);
        })
    });
});
console.log(result);


How you are generating the HTML? If you are using PHP you could just pass the variables to JS rather than trying to read them later from HTML. For example if you have them in array, could use json_encode in PHP and then echo that in your page inside variables = jQuery.parseJSON(here);

Now if you cannot do this, and you really want to read it from HTML, you should then first select the id data with $('#data') and take its children(). Then use .each() for the children. Then put the child to object and then check its each children() with .each() and add them to your object. If you may have more than just those levels I recommend doing a recursive function for this.

PS: I dont think its proper HTML to put Span between UL and LI.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜