Search code examples
jqueryjsonloopstraversalnested-loops

Structuring a Nested Loop for Table Creation


I've got the looping thing for table rows down pretty much, but when I want to create header <th> rows, I am at a loss.

For instance, I can traverse down to grab the "Auto Brand" and make a table containing the brand name and specifics in ONE normal table row from the first member, but getting the nested loop to keep going for all "sibling" arrays is driving me bonkers. I can't go the simple route and just use the array name as it isn't "human friendly"

Imagine the following:

a-r: [{
    country: "Italy",
    id: "194",
    type: "sports",
    style: {
        doors: "2",
        layout: "rwd"
    },
    model: {
        name: "Alfa Romeo",
        marque: "Spider",
        slug: "alfa-romeo-spider",
        id: "59"
    },
    url: "http://www.alfaromeo.it"
}, {
    country: "Italy",
    id: "195",
    type: "sports",
    style: {
        doors: "2",
        layout: "rwd"
    },
    model: {
        name: "Alfa Romeo",
        marque: "Graduate",
        slug: "alfa-romeo-graduate",
        id: "60"
    },
    url: "http://www.alfaromeo.it"
}],
packard: [{
    country: "USA",
    id: "200",
    type: "sedan",
    style: {
        doors: "4",
        layout: "rwd"
    },
    model: {
        name: "Packard",
        marque: "Phantom",
        slug: "packard-phantom",
        id: "80"
    },
    url: "http://www.packard.com"
}, {
    country: "USA",
    id: "220",
    type: "coupe",
    style: {
        doors: "2",
        layout: "rwd"
    },
    model: {
        name: "Packard",
        marque: "626",
        slug: "packard-626",
        id: "305"
    },
    url: "http://www.packard.it"
}],[...]

So, I need to basically traverse down to the first "model.name" instance, grab that value and slam it into the table header or caption... whatever.

Then I need to run another loop to just grab the country[value], type[value], model.marque[value] and put those into rows for every member of the array and close the table... ad nauseam.

My end result would look like:

<table>
 <thead>
  <tr>
    <th colspan=3>Obj.model.name</th>
  </tr>
 </thead>
 <tbody>
   <tr>
    <td>Obj.model.marque</td><td>Obj.country</td><td>Obj.type</td>
   </tr>
   <tr>
    <td>{...}</td><td>{...}</td><td>{...}</td>
   </tr>
   <tr>
    <td>{...}</td><td>{...}</td><td>{...}</td>
   </tr>
 </tbody>
</table>

I am trying to somehow, in the loop, grab that initial model.name[value], hold it, then loop over all the siblings and put the rows together.... i just figure if I do this, I am declaring (and constructing) the header/caption for every row which is obviously not desired.

I thank you Traversal Masters and Mistresses for any insight you can provide. I am getting old, and my brain has been melted from the heatwave as of late.


Solution

  • You mostly just need to remember the current name outside of the loop, and create a new table (with a new header) each time it changes:

    var name = null;
    var table = null;
    
    $.each(a, function(k, v) {
        $(v).each(function() {
    
            if (this.model.name !== name) {
                name = this.model.name;
                table = $('<table>').appendTo(document.body);
                var thead = $('<thead>').appendTo(table);
                $('<th>', {
                    colspan: 3,
                    text: name
                }).appendTo(thead);
            }
    
            $('<tr>').appendTo(table).append(
                $('<td>', { text: this.model.marque }),
                $('<td>', { text: this.country }),
                $('<td>', { text: this.type })
            );
        });
    });
    

    demo at http://jsfiddle.net/alnitak/2jvSS/