espresso_coffee
espresso_coffee

Reputation: 6110

How to build dynamic table using JQuery?

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

Answers (3)

Junius L
Junius L

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

Taplar
Taplar

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

Mirnamiq Abdullayev
Mirnamiq Abdullayev

Reputation: 171

Object.keys(data).forEach(function(item, key){ data[item].fname });

Upvotes: -2

Related Questions