Reputation: 1862
I have a problem building a HTML table from the following JSON
[
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children":[
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
}
]
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
}
]
when fed into these functions
function getRowHTML(dataObject, type) {
cycles = dataObject.length;
var markup = '';
for (var i=0; i < cycles; i++) {
// different markup for each line
switch (type) {
case 'size':
markup += ' <td>' + dataObject[i].size + '</td>';
break;
case 'price':
markup += ' <td>' + addDots(dataObject[i].price) + '€ </td>';
break;
case 'type':
markup += ' <td>' + dataObject[i].type + '</td>';
break;
}
// Check if an object has children and insert children HTML as well
if (dataObject[i].children) {
markup += getRowHTML(dataObject[i].children,type);
}
}
return markup;
}
function getHTML(data) {
var markup = '<table>';
markup += '<tr class="odd">' + getRowHTML(data,'size') + '</tr>';
markup += '<tr class="even">' + getRowHTML(data,'price') + '</tr>';
markup += '<tr class="odd">' + getRowHTML(data,'type') + '</tr>';
markup += '</table>';
return markup;
}
Everything works fine until I add the check for children and the corresponding recursive function call.
Then the result are the first two objects and the children but the last one won't be in the table. Any ideas?
Upvotes: 2
Views: 3087
Reputation: 536349
You have forgotten the var
on the cycles
variable, making it an accidental global. The inner call to getRowHTML
overwrites the value of the global cycles
in the outer call, making the outer loop end early.
Note you also have HTML-injection problems if any of the properties can contain HTML-special characters. You should HTML-escape any content being inserted into an HTML string. Or, to avoid having to think about that, use DOM methods to create the table instead. eg.
function fillRow(row, items, property) {
for (var i= 0, n= items.length; i<n; i++) {
var item= items[i];
var s= item[property];
if (property==='price')
s= addDots(s)+'\u20Ac'; // €
row.insertCell(-1).appendChild(document.createTextNode(s));
if (item.children)
fillRow(row, item.children, property);
}
}
function makeTable(data) {
var table= document.createElement('table');
var properties= ['size', 'price', 'type'];
for (var i= 0, n= properties.length; i<n; i++) {
var row= table.insertRow(-1);
row.className= i%2===0? 'odd' : 'even';
fillRow(row, data, properties[i]);
}
return table;
}
Upvotes: 2