I often use template literals for this, constructing a long string of HTML using the += operator and then using document.innerHTML to append the final HTML string to my page.
A simple example might look like this:
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
let listMarkup = '';
for (let i = 0; i < helloWorldsKeys.length; i++) {
listMarkup += '<li class="listItem">' + helloWorlds[helloWorldsKeys[i]] + '</li>';
}
const myList = document.getElementById("list");
myList.innerHTML = listMarkup;
<div>
<h1>Hello World!</h1>
<ul id="list"></ul>
</div>
Of course, you can also use appendChild to construct the list bit by bit in the client rather than adding the whole list at once. This might look like:
const myList = document.getElementById("list");
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
for (let i = 0; i < helloWorldsKeys.length; i++) {
let listItem = document.createElement('li');
listItem.classList.add('listItem');
listItem.innerHTML = helloWorlds[helloWorldsKeys[i]];
myList.appendChild(listItem);
}
<div>
<h1>Hello World!</h1>
<ul id="list"></ul>
</div>
Here's an example using a table:
const myTableBody = document.getElementById("my-table-body");
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
for (let i = 0; i < helloWorldsKeys.length; i++) {
// create a table row element
let tableRow = document.createElement('tr');
// create a table cell (td) element
let listItem = document.createElement('td');
listItem.classList.add('listItem');
// add content to table cell element
listItem.innerHTML = helloWorlds[helloWorldsKeys[i]];
// append table cell to table row
tableRow.appendChild(listItem);
// append table row to table body
myTableBody.appendChild(tableRow);
}
<table border="1">
<thead>
<td>Hello World!</td>
</thead>
<tbody id="my-table-body"></tbody>
</table>
Regarding your specific application, check out this answer if you want to explore creating HTML documents and appending their contents to other HTMl documents: Cannot append DOM element to DIV node: Uncaught HierarchyRequestError: Failed to execute 'appendChild' on 'Node'
Answer from jaredgorski on Stack OverflowVideos
I often use template literals for this, constructing a long string of HTML using the += operator and then using document.innerHTML to append the final HTML string to my page.
A simple example might look like this:
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
let listMarkup = '';
for (let i = 0; i < helloWorldsKeys.length; i++) {
listMarkup += '<li class="listItem">' + helloWorlds[helloWorldsKeys[i]] + '</li>';
}
const myList = document.getElementById("list");
myList.innerHTML = listMarkup;
<div>
<h1>Hello World!</h1>
<ul id="list"></ul>
</div>
Of course, you can also use appendChild to construct the list bit by bit in the client rather than adding the whole list at once. This might look like:
const myList = document.getElementById("list");
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
for (let i = 0; i < helloWorldsKeys.length; i++) {
let listItem = document.createElement('li');
listItem.classList.add('listItem');
listItem.innerHTML = helloWorlds[helloWorldsKeys[i]];
myList.appendChild(listItem);
}
<div>
<h1>Hello World!</h1>
<ul id="list"></ul>
</div>
Here's an example using a table:
const myTableBody = document.getElementById("my-table-body");
const helloWorlds = {
spanish: '¡Hola Mundo!',
polish: 'Witaj świecie!',
french: 'Bonjour le monde!'
}
const helloWorldsKeys = Object.keys(helloWorlds);
for (let i = 0; i < helloWorldsKeys.length; i++) {
// create a table row element
let tableRow = document.createElement('tr');
// create a table cell (td) element
let listItem = document.createElement('td');
listItem.classList.add('listItem');
// add content to table cell element
listItem.innerHTML = helloWorlds[helloWorldsKeys[i]];
// append table cell to table row
tableRow.appendChild(listItem);
// append table row to table body
myTableBody.appendChild(tableRow);
}
<table border="1">
<thead>
<td>Hello World!</td>
</thead>
<tbody id="my-table-body"></tbody>
</table>
Regarding your specific application, check out this answer if you want to explore creating HTML documents and appending their contents to other HTMl documents: Cannot append DOM element to DIV node: Uncaught HierarchyRequestError: Failed to execute 'appendChild' on 'Node'
The problem I see here is that you're using tbody.innerHTML = html; instead of tbody.innerHTML += html;, when you use += operator you keep the old HTML, if you use = you replace the old HTML with the new HTML
» npm install vanilla-datatables
DataTables lets you define the structure and data of the table programmatically using what they call "data sources".
There are a few examples in the documentation. I'm not sure which one will suit you but here are a few to get you started:
- DataTables dynamic creation example (uses a JS array)
- DataTables AJAX source example (uses a JS array through AJAX)
You could combine that with the bDestroy() method to avoid recreating the <table> tag.
A different approach would be to re-set the rows without recreating the table. There is no setData() method that I know of, but you could use the fnClearTable() and fnAddData() methods to achieve the same result. You can read more about these methods in the DataTables API docs.
hello i had the same issue... and this was how i solved it...
i had this function in a laravel controller... that loops and creates a table dynamically.. based on the $app_id variable... and i had to append the datatable to it... at runtime...
public function getAppUserProfile(Request $request){
$app_id = $request['appId'];
$configs = Userconfig::with('user')->where('config_id', $app_id)->get();
$ct = 1;
$str = '';
foreach($configs as $config){
// $config->user->id,
$str .= '<tr><td>'. $ct.'</td><td>'.
$config->user->profile->first_name
.'</td><td>'.
$config->user->profile->first_name
.'</td><td>'.
$config->user->profile->first_name
.'</td></tr>';
$ct++;
}
$tb = '<table id="testTable2" class="table table-striped table-bordered"><thead>';
$tb .= '<tr><th>S/N</th><th>USER NAME</th><th>ASSIGN ROLE</th><th>Add</th></tr>';
$tb .= '</thead><tbody>' . $str . '</tbody></table>';
//return json_encode($configs);
}
the $str function is what holds the constructed table data... and i echo the table to the page directly into the div tag with id " panel_data_tb ", which is done on the javascript file..
function showAppUser() {
$('.loading').css('display', 'block');
var appID = $('#app_search').val();
$.ajax({
method: 'get',
url: getauprofile,
data: {appId: appID}
})
.done(function (result) {
// alert('success ' + result);
$('#panel_data_tb').html(result);
$('.loading').css('display', 'none');
//this line here is what initializes the datatable on the
//current table just being created...
//dynamically.. and it worked. perfectly for me..
//******************************************************
$('#panel_data_tb').find('table').DataTable();
//*******************************************************
});
}
the last line.. finds the table within the Div tag and initializes the datatable() property on it dynamically. so anytime you change the contents of the table, the datatable is re-initialized on the dynamic table being created..
i hope this helps. thanks.