Reputation: 6110
I would like to build dynamic table using JQuery and then append the table to DOM. Usually I used string concatenation method to build the table. This time I would like to do this with JQuery. One thing that I'm struggling to get is opening/closing tr
element while looping over multiple rows. Here is example if my code:
var data = {
"1": {
"fname": "Jon",
"lname": "Wayne",
"dob": "05/14/1987",
"status": "Active",
"color": "Red",
"team": "Miami"
},
"2": {
"fname": "Tim",
"lname": "Ryan",
"dob": "01/23/1967",
"status": "Inactive",
"color": "Blue",
"team": "Chicago"
},
"3": {
"fname": "Jim",
"lname": "Carey",
"dob": "11/02/1997",
"status": "Suspended",
"color": "Yellow",
"team": "Denver"
},
"4": {
"fname": "Chuck",
"lname": "Norris",
"dob": "09/06/1945",
"status": "Active",
"color": "Green",
"team": "Boston"
}
}
$('#start').on('click', showRecords);
function showRecords() {
displayData(1,data);
}
function displayData(fnid,data) {
var tbl = $('<table>').addClass('display').prop('id','data_tbl'),
thead = $('<thead>'),
tbody = $('<tbody>'),
tr = $('<tr>');
title = ['First Name','Last Name','DOB','Status','Color','Team'];
/*** Start: Table Header ***/
thead.append('<tr>');
for(var i=0; i < title.length; i++) {
if(fnid == 1){
if(i <= 3) {
thead.append($('<th>').text(title[i]));
}
}else{
thead.append($('<th>').text(title[i]));
}
}
thead.append('</tr>');
/*** End: Table Header ***/
/*** Start: Table Body ***/
for(key in data) {
tbody.append('<tr>');
tbody.append($('<td>').text(data[key].fname));
tbody.append($('<td>').text(data[key].lname));
tbody.append($('<td>').text(data[key].dob));
tbody.append($('<td>').text(data[key].status));
if(fnid !== 1) {
tbody.append($('<td>').text(data[key].color));
tbody.append($('<td>').text(data[key].team));
}
tbody.append('</tr>');
}
/*** End: Table Body ***/
tbl.append(thead); // Append header section to table.
tbl.append(tbody); // Append body section to table.
$("#container").empty().append(tbl);
}
.display {
width: 500px;
background-color: red;
}
.display,
.display th,
.display td{
border: 1px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" name="start" id="start" value="Start" />
<div id="container"></div>
At first look you would think that everything is fine with the code, but if you open your dev tools and inspect the table elements you will find the issues. There are tr
elements in thead
and tbody
that are empty. These elements should not be there. Can anyone tell me how I can open/close the tr element in JQuery and build the table properly? Thank you.
Upvotes: 2
Views: 1420
Reputation: 16152
Use Object.keys to loop over your object.
var data = {
"1": {
"fname": "Jon",
"lname": "Wayne",
"dob": "05/14/1987",
"status": "Active",
"color": "Red",
"team": "Miami"
},
"2": {
"fname": "Tim",
"lname": "Ryan",
"dob": "01/23/1967",
"status": "Inactive",
"color": "Blue",
"team": "Chicago"
},
"3": {
"fname": "Jim",
"lname": "Carey",
"dob": "11/02/1997",
"status": "Suspended",
"color": "Yellow",
"team": "Denver"
},
"4": {
"fname": "Chuck",
"lname": "Norris",
"dob": "09/06/1945",
"status": "Active",
"color": "Green",
"team": "Boston"
}
}
$('#start').on('click', showRecords);
function showRecords() {
displayData(1,data);
}
function displayData() {
const table = $("<table></table>").addClass('display');
Object.keys(data).forEach(item => {
const row = $("<tr></tr>");
Object.keys(data[item]).forEach(key => {
const rowData = $("<td></td>")
.addClass("bar")
.text(data[item][key]);
row.append(rowData);
});
table.append(row);
});
$("#container").empty().append(table);
}
.display {
width: 500px;
background-color: red;
}
.display,
.display th,
.display td{
border: 1px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" name="start" id="start" value="Start" />
<div id="container"></div>
Upvotes: 2
Reputation: 24965
I would suggest extracting your html out into a template. That way your script is cleaned up and you separate your markup from your logic more so. The following logic uses the created template and then only has to construct the cells for the tbody. It constructs the cells in an array of string using map, which then all the strings get appended to the tbody at once.
var data = {
"1": {
"fname": "Jon",
"lname": "Wayne",
"dob": "05/14/1987",
"status": "Active",
"color": "Red",
"team": "Miami"
},
"2": {
"fname": "Tim",
"lname": "Ryan",
"dob": "01/23/1967",
"status": "Inactive",
"color": "Blue",
"team": "Chicago"
},
"3": {
"fname": "Jim",
"lname": "Carey",
"dob": "11/02/1997",
"status": "Suspended",
"color": "Yellow",
"team": "Denver"
},
"4": {
"fname": "Chuck",
"lname": "Norris",
"dob": "09/06/1945",
"status": "Active",
"color": "Green",
"team": "Boston"
}
}
$('#start').on('click', showRecords);
function showRecords() {
displayData(1,data);
}
function displayData(fnid,data) {
var template = $('#tableTemplate').html();
var $table = $(template);
$table.find('tbody').append(
Object.keys(data[fnid]).map(function(key){
return '<td>'+ data[fnid][key] +'</td>';
})
);
$("#container").empty().append($table);
}
.display {
width: 500px;
background-color: red;
}
.display,
.display th,
.display td{
border: 1px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" name="start" id="start" value="Start" />
<div id="container"></div>
<script type="text/html" id="tableTemplate">
<table class="display" id="data_tbl">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>DOB</th>
<th>Status</th>
<th>Color</th>
<th>Team</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</script>
Upvotes: 1
Reputation: 171
Object.keys(data).forEach(function(item, key){ data[item].fname });
Upvotes: -2