Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question
1  
It's not JSON. It is just a JavaScript object. –  Felix Kling Jul 6 '11 at 6:48
    
i dont see a regular pattern in your html. you will have to do it manually –  Ibu Jul 6 '11 at 6:48
    
Where does this html reside? I think that perhaps what you are trying to accomplish has a different solution. I would probably use XLST since that's what I know but it's hard to figure out from your text what you want.' –  elgrego Jul 6 '11 at 6:52
    
XSLT to generate json.. suuuuuuure. –  ThiefMaster Jul 6 '11 at 7:09
    
@Felix: True, I'm saving it to JSON in localStorage. –  Josiah Jul 6 '11 at 19:19

3 Answers 3

up vote 2 down vote accepted

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.

share|improve this answer
    
That did the trick! Thanks so much! –  Josiah Jul 6 '11 at 19:19

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);
share|improve this answer
    
Thanks for the help! –  Josiah Jul 6 '11 at 19:28

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.

share|improve this answer
    
Good point regarding the span in the ul... –  Felix Kling Jul 6 '11 at 7:32
    
Thanks for the response! The HTML is populated from a var parsed from JSON in localStorage - which was pretty easy. I got stuck trying to figure out how to save changes made to the object before saving it back to localStorage with JSON.stringify. Regarding span and ul: Yes! That was for simplification in my question:). Thanks again! –  Josiah Jul 6 '11 at 19:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.