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 Overflow
🌐
CSS Script
cssscript.com › home › categories › table › dynamic data table in vanilla javascript
Dynamic Data Table In Vanilla JavaScript | CSS Script
July 14, 2018 - A pure Vanilla JavaScript based data table component that features dynamic tabular data, table filtering, sorting, paginating and many more.
🌐
plainJS
plainjs.com › javascript › plugins › vanilla-datatables-125
Vanilla-DataTables
Create dynamic tables - a vanilla JS version of the jQuery DataTables plugin.
Top answer
1 of 3
2

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'

2 of 3
0

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

🌐
freeCodeCamp
freecodecamp.org › news › how-to-create-and-style-tables-with-vanilla-javascript
How to Create and Style Tables with Vanilla JavaScript
October 27, 2025 - You want to sort, filter, or paginate your table interactively. JavaScript lets you build tables programmatically by defining data in an array or object and letting code handle the rendering.
🌐
CSS Script
cssscript.com › home › categories › table › full-featured dynamic data grid in vanilla javascript – jsdatatable
Full-featured Dynamic Data Grid In Vanilla JavaScript - jsdatatable | CSS Script
September 14, 2019 - Render a data table on the page. const table = document.querySelector('#table'); Table.init(table, myData, myOptions); Lightweight JavaScript Data Grid with Search, Sort, and CSV Export – peggrid.js
🌐
Medium
medium.com › @nikhiljain195_64995 › how-to-create-datatable-using-vanilla-javascript-108c1e370504
How to Create Data-table using vanilla JavaScript | by Nikhil | Medium
June 14, 2022 - The function displayTable() needs to be async as it needs to wait until we have fetched the data from the endpoint. Instead of hard coding the table-headings we can generate them dynamically by extracting the keys from any object as shown in fetchHeading function below.
🌐
jQuery Script
jqueryscript.net › jquery plugins › jquery table plugins
Dynamic Table Creator In jQuery & Vanilla JS - TableFilerExt | Free jQuery Plugins
January 2, 2020 - // Vanilla JavaScript let table = document.getElementById("table"); table.addThs("H1",2,"H2","H3") .addTds("A1",2,"F1","F2") // jQuery let table = $("#table"); table.addThs("H1",2,"H2","H3") .addTds("A1",2,"F1","F2") 4. That's it. The empty table will be populated with the data you provide as follows:
🌐
GitHub
github.com › kaneymhf › JSDataTable
GitHub - kaneymhf/JSDataTable: DataTables made in Vanilla JS - With advanced functions, select rows and sort accented words
const dataTable = new jsdatatables.JSDataTable("#myTable", { searchable: false, fixedHeight: true, ...
Author   kaneymhf
Find elsewhere
🌐
GitHub
github.com › Mobius1 › Vanilla-DataTables
GitHub - Mobius1/Vanilla-DataTables: A lightweight, dependency-free javascript HTML table plugin · GitHub
A lightweight, extendable, dependency-free javascript HTML table plugin. Similar to jQuery DataTables, but without the dependencies. ... <link href="https://unpkg.com/vanilla-datatables@latest/dist/vanilla-dataTables.min.css" rel="stylesheet" ...
Starred by 379 users
Forked by 78 users
Languages   JavaScript 95.2% | CSS 4.1% | HTML 0.7%
🌐
jQuery Script
jqueryscript.net › blog › best-data-table-grid.html
10 Best Data Table/Grid Systems In JavaScript (2026 Update) | jQuery Script
10 best jQuery & Vanilla JavaScript plugin to generate flexible, dynamic data tables (data grids) on the web applications.
🌐
DataTables
datatables.net › examples › data_sources › js_array.html
DataTables example - JavaScript sourced data
A table must be available on the page for DataTables to use. This examples shows an empty table element being initialising as a DataTable with a set of data from a JavaScript array. The columns in the table are dynamically created based on the columns.title configuration option.
🌐
CodePen
codepen.io › Mobius1 › pen › VadmKb
Vanilla DataTables
body { background-color: #efefef; align-items: center; color: #333; font-family: "Roboto"; font-weight: 400; margin: 0; } .container { margin-top: 5%; } a, a:hover, a:focus, a:active { color: #333; outline: medium none; text-decoration: none; } .btn.active.focus, .btn.active:focus, .btn.focus, .btn.focus:active, .btn:active:focus, .btn:focus { outline: medium none; } #ribbon { background: #fff none repeat scroll 0 0; box-shadow: 0 0 10px 0 rgba(0,0,0,0.1); font-weight: 400; padding: 15px; position: fixed; right: -269px; text-align: center; top: -125px; transform: rotate(45deg); transform-origin: 0 0 0; width: 500px; i { font-size: 21px; padding-right: 5px; vertical-align: middle; } } .dataTable-sorter::before { bottom: 8px; } .dataTable-sorter::after { top: 8px; } .selected { td { background-color: #27ae60; color: #fff; } }
🌐
GitHub
github.com › abhijit-paul › custom-datatable
GitHub - abhijit-paul/custom-datatable: Dynamic JSON based HTML data table written using vanilla JS
Vanilla JS based dynamically generated datatable. Does not use any third party javascript library ... Open app.html in any browser. Dynamic JSON based HTML data table written using vanilla JS
Author   abhijit-paul
🌐
simple-datatables
fiduswriter.github.io › simple-datatables › documentation
simple-datatables | DataTables but in TypeScript transpiled to Vanilla JS
Dynamically Adding Data · Add columns from remote source · Colspan Support · Rowspan Support · datatable.init · datatable.refresh · datatable.update · datatable.page · datatable.sort · datatable.perpage · datatable.search · datatable.multisearch ·
🌐
Medium
medium.com › @anuhyadigital › data-table-in-java-script-63f9d4ee36a5
Data Table in Java Script. In our previous blog post we had… | by Anuhya digital | Medium
November 8, 2024 - Using the JavaScript forEach method, we loop through the array and dynamically add rows to the table. This can be expanded to include data fetched from external sources like APIs.
🌐
npm
npmjs.com › package › vanilla-datatables
vanilla-datatables - npm
September 25, 2018 - <script src="https://cdn.jsdelivr.net/npm/vanilla-datatables@latest/dist/vanilla-dataTables.min.js" type="text/javascript"></script> You can replace latest with the required release number. CDNs courtesy of unpkg and jsDelivr · Then just initialise the plugin by either passing a reference to the table or a CSS3 selector string as the first parameter: var myTable = document.querySelector("#myTable"); var dataTable = new DataTable(myTable); // or ·
      » npm install vanilla-datatables
    
Published   Sep 25, 2018
Version   1.6.16
Author   Karl Saunders
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › API › Document_Object_Model › Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces
Traversing an HTML table with JavaScript and DOM Interfaces
const myBody = document.getElementsByTagName("body")[0]; const myTable = myBody.getElementsByTagName("table")[0]; const myTableBody = myTable.getElementsByTagName("tbody")[0]; const myRow = myTableBody.getElementsByTagName("tr")[1]; const myCell = myRow.getElementsByTagName("td")[1]; // first item element of the childNodes list of myCell const myCellText = myCell.childNodes[0]; // content of currentText is the data content of myCellText const currentText = document.createTextNode(myCellText.data); myBody.appendChild(currentText); At the end of sample1 there is a call to setAttribute on the myTable object. This call was used to set the border property of the table. To retrieve the value of the attribute, use the getAttribute method: ... Once you have the object in your JavaScript variable, you can set style properties directly.
Top answer
1 of 2
6

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.

2 of 2
1

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.

🌐
CSS Script
cssscript.com › home › categories › table › dynamic sortable filterable data table in pure javascript – simpletable
Dynamic Sortable Filterable Data Table In Pure JavaScript - simpleTable | CSS Script
September 28, 2020 - simpleTable is a vanilla JavaScript library to dynamically renders a sortable, filterable, scrollable, editable data table from JavaScript/JSON data.
🌐
Webslesson
webslesson.info › 2021 › 08 › server-side-processing-vanilla-javascript-datatables-in-php.html
Server Side Processing Vanilla JavaScript DataTables in PHP | Webslesson
This JSTable is a pure vanilla JavaScript based datatable component and it has features like we can load dynamic tabular data, we can filter or search data, we can sort data, it has automatically make pagination link and many more.