patternjavascriptMinor
Output JavaScript object into HTML table of key-value pairs using jQuery
Viewed 0 times
javascriptintotableoutputvaluejqueryusingobjectpairshtml
Problem
This function is meant to take an object, loop through the key-values and generate/build a HTML table at a particular ID:
This function is then used, along with a number of D3 scripts, to populate elements on the DOM:
Any comments about how this is being achieved? Am I overlooking either a basic tenant of how JS "should" be used (this is a huge side-effect for instance, should I be returning a formatted string then placing that string into the DOM for instance) or over-complicating things by jQuery'ing a bunch of times?
function insertBasicTable(basic_data, insert_id) {
/* Insert the key/value pairs into a table element on the DOM.
basic_data = object containing key/value pairs
insert_id = the id on the DOM to insert the table into
Intentionally not including closing tags in the jquery requests;
http://stackoverflow.com/a/14737115/2355035 */
table_id = '#' + insert_id;
var array_length = Object.keys(basic_data).length;
var array_obj_names = Object.keys(basic_data);
// create the table header
$(table_id).empty();
$(table_id).append('');
$(table_id).find('thead:last').append('Tag');
$(table_id).find('thead:last').append('Data');
// begin the table body and iterate through key/value pairs
$(table_id).append('');
for (var i = 0; i ' + array_obj_names[i];
var data = '' + basic_data[attr_name];
$(table_id).find('tbody:last').append('' + tag + data);
}
}This function is then used, along with a number of D3 scripts, to populate elements on the DOM:
linePlot.render(someObject.modules.qual.quintiles);
boxPlot.render(someObject.modules.qual.quintiles);
insertBasicTable(someObject.modules.basic, 'basic-stats-table');
// etc, etc...Any comments about how this is being achieved? Am I overlooking either a basic tenant of how JS "should" be used (this is a huge side-effect for instance, should I be returning a formatted string then placing that string into the DOM for instance) or over-complicating things by jQuery'ing a bunch of times?
Solution
Let's start with your version:
1) Unnecessary optimization.
This gives you nothing in terms of performance. It would be optimized away by the browser.
2) Chain-calling
It is possible to do chain-calls like:
3) Misunderstanding calls
4) NuStyleLoopz
You could iterate over the keys directly via
-
Array.prototype.forEach()
-
Array.prototype.map()
-
Array.protoype.reduce() / Array.prototype.reduceRight().
Here a slighty pimped version:
Here is the fiddle to play with.
To make HTML-generation less painfull and a bit more JS-stylish I define what is called a higher order function
1) Unnecessary optimization.
var array_length = Object.keys(basic_data).length;
var array_obj_names = Object.keys(basic_data);This gives you nothing in terms of performance. It would be optimized away by the browser.
2) Chain-calling
$(table_id).empty();
$(table_id).append('');It is possible to do chain-calls like:
$('#elem').doA().doB().doC()3) Misunderstanding calls
$(table_id).find('thead:last').append('Tag');.append() does exactly that: appending after the last element.4) NuStyleLoopz
for (var i = 0; i ' + array_obj_names[i];
var data = '' + basic_data[attr_name];You could iterate over the keys directly via
Object.keys() with-
Array.prototype.forEach()
-
Array.prototype.map()
-
Array.protoype.reduce() / Array.prototype.reduceRight().
Here a slighty pimped version:
makeTag=function(openTag, closeTag){
return function(content){
return openTag+content+closeTag;
};
};
tHead=makeTag("","");
tBody=makeTag("","");
td=makeTag("","");
tr=makeTag("","");
function insertBasicTable(data,id){
$('#'+id).html(
tHead(
tr(
td("Tag")+
td("Data")
)
)+
tBody(
Object.keys(data).reduce(function(o,n){
return o+tr(
td(n)+""+
td(data[n]+"")
);
},"")
)
);
};
insertBasicTable({"key1":"value1","key2":"value2"},"mytable");Here is the fiddle to play with.
To make HTML-generation less painfull and a bit more JS-stylish I define what is called a higher order function
makeTag: simply a function returning a function. A call to var tHead=makeTag("",""); generates an anonymous function (a function without name), which returns every time it's called "`"+ parameter +"". The same goes for the other tags. This allows me to do something like a DSL:
tHead(
tr(
td("Tag")+
td("Data")
)
)
That is not only handy, but cool B-)
Besides it is nearly as readable as html` and not so noisy like the typical string concatenation and the risk of typos is really low.Code Snippets
var array_length = Object.keys(basic_data).length;
var array_obj_names = Object.keys(basic_data);$(table_id).empty();
$(table_id).append('<thead>');$(table_id).find('thead:last').append('<th>Tag');for (var i = 0; i < array_length; i++) {
var attr_name = array_obj_names[i];
var tag = '<td>' + array_obj_names[i];
var data = '<td>' + basic_data[attr_name];makeTag=function(openTag, closeTag){
return function(content){
return openTag+content+closeTag;
};
};
tHead=makeTag("<thead>","</thead>");
tBody=makeTag("<tbody>","</tbody>");
td=makeTag("<td>","</td>");
tr=makeTag("<tr>","</tr>");
function insertBasicTable(data,id){
$('#'+id).html(
tHead(
tr(
td("Tag")+
td("Data")
)
)+
tBody(
Object.keys(data).reduce(function(o,n){
return o+tr(
td(n)+""+
td(data[n]+"")
);
},"")
)
);
};
insertBasicTable({"key1":"value1","key2":"value2"},"mytable");Context
StackExchange Code Review Q#77286, answer score: 7
Revisions (0)
No revisions yet.