148

How can I delete all rows of an HTML table except the <th>'s using Javascript, and without looping through all the rows in the table? I have a very huge table and I don't want to freeze the UI while I'm looping through the rows to delete them

JJJ
  • 32,902
  • 20
  • 89
  • 102
K''
  • 5,020
  • 7
  • 33
  • 43

27 Answers27

126

this will remove all the rows:

$("#table_of_items tr").remove(); 
Pete
  • 57,112
  • 28
  • 117
  • 166
Apparao
  • 1,634
  • 1
  • 12
  • 17
  • 62
    If you don't want to delete the header: $("#table_of_items tbody tr").remove(); – TTT Aug 07 '14 at 20:34
  • 2
    Very good simple answer. I used in my CoffeeScript - I like one-line-solutions `$("tbody#id tr").remove()` – n2o Aug 29 '14 at 10:35
  • I think this is better answer than the accepted one, though it depends on whether you want to use JQuery or not. But somehow .remove did not work on Chrome. – Milind Thakkar Sep 22 '15 at 12:43
  • TTT, use tags to create head for table. Then $("#table_of_items tr").remove(); works fine for you, because it removes only tags. – Kate May 27 '16 at 15:19
  • TTT, please add the your comment to the answer. Your answer is perfect! – Khorshid Dec 05 '19 at 07:40
  • 10
    Bad answer - that is not JavaScript - that is JQuery (not what the OP asked for). I think this **only works 1 time** as well - if you try to do it a *second* time (e.g. after adding more rows) I see the error "Uncaught TypeError: Cannot read properties of null (reading 'remove')" - so for anyone looking for a JavaScript solution to this (like the OP asked for): .remove() is probably the wrong idea? (at least without an extra step to put back something new that can again be later removed). Setting to '' is safer than .remove(): e.g. `document.getElementById('mytbody').innerHTML = ''; ` –  Oct 02 '21 at 03:15
110

Keep the <th> row in a <thead> and the other rows in a <tbody> then replace the <tbody> with a new, empty one.

i.e.

var new_tbody = document.createElement('tbody');
populate_with_new_rows(new_tbody);
old_tbody.parentNode.replaceChild(new_tbody, old_tbody)
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Easily the most efficient solution, provided of course that the JavaScript developer is allowed to modify the HTML. – Blazemonger Sep 01 '11 at 14:26
  • 1
    Beware, if you are going to replace the tbody using the innerHTML property, it won't work in IE, there's a workaround though. – aziz punjani Sep 01 '11 at 14:30
  • 2
    @Eonasdan — That's somewhat subjective. There are plenty of libraries out there (my personal preference would be to use YUI 3 these days) should someone with this problem want to solve this problem with one of them. The principles are going to be the same no matter which huge chunk of third party code you wish to include though. – Quentin Sep 02 '11 at 12:47
  • 7
    Necromancing this... what's wrong with: `document.getElementById('tbody').innerHTML = '';` – Trees4theForest Apr 13 '17 at 01:47
  • 2
    @Trees4theForest This works fine for me. Probably it wasn't possible at the time of OP. – Mabu May 13 '20 at 14:51
95

Very crude, but this also works:

var Table = document.getElementById("mytable");
Table.innerHTML = "";
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Marcel
  • 983
  • 6
  • 2
  • 16
    Unfortunately this does not keep the headers as the OP asks. – JoSeTe4ever Mar 01 '16 at 17:05
  • 3
    It does if they put their headers `` nested in a ``. This is probably the most syntactically correct way to build the table anyways. – Jon Feb 23 '18 at 16:38
  • Works great. I think this is suitable for only people like me, who has created table header , row, cell, tbody everything in JQuery. – Shamsul Arefin Aug 02 '18 at 06:56
  • This worked well for just clearing the html inside a tbody :) – RudyOnRails Oct 05 '18 at 23:19
  • 1
    I cleared just the body with a slight modification to this `var bodyRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];` `bodyRef.innerHTML = '';` – azyth Feb 22 '19 at 17:34
  • 4
    This answer solution didn't work for me (it removed both the thead and tbody). I lost my headers. But @azyth's solution (in the comment) worked really well. Editted for typo. – Kenny Pyatt Aug 19 '21 at 19:18
  • What is the advantage of using a variable, so just `document.getElementById("mytable")...` works. – Timo May 13 '22 at 19:36
31

Points to note, on the Watch out for common mistakes:

If your start index is 0 (or some index from begin), then, the correct code is:

var tableHeaderRowCount = 1;
var table = document.getElementById('WRITE_YOUR_HTML_TABLE_NAME_HERE');
var rowCount = table.rows.length;
for (var i = tableHeaderRowCount; i < rowCount; i++) {
    table.deleteRow(tableHeaderRowCount);
}

NOTES

1. the argument for deleteRow is fixed
this is required since as we delete a row, the number of rows decrease.
i.e; by the time i reaches (rows.length - 1), or even before that row is already deleted, so you will have some error/exception (or a silent one).

2. the rowCount is taken before the for loop starts since as we delete the "table.rows.length" will keep on changing, so again you have some issue, that only odd or even rows only gets deleted.

Hope that helps.

Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
21

This is an old question, however I recently had a similar issue.
I wrote this code to solve it:

var elmtTable = document.getElementById('TABLE_ID_HERE');
var tableRows = elmtTable.getElementsByTagName('tr');
var rowCount = tableRows.length;

for (var x=rowCount-1; x>0; x--) {
   elmtTable.removeChild(tableRows[x]);
}

That will remove all rows, except the first.

Cheers!

cstrat
  • 1,007
  • 10
  • 17
15

If you can declare an ID for tbody you can simply run this function:

var node = document.getElementById("tablebody");
while (node.hasChildNodes()) {
  node.removeChild(node.lastChild);
}
OSB
  • 159
  • 1
  • 3
13

Assuming you have just one table so you can reference it with just the type. If you don't want to delete the headers:

$("tbody").children().remove()

otherwise:

$("table").children().remove()

hope it helps!

10

I needed to delete all rows except the first and solution posted by @strat but that resulted in uncaught exception (referencing Node in context where it does not exist). The following worked for me.

var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>0; x--) {
   myTable.deleteRow(x);
}
lkan
  • 109
  • 1
  • 2
9

the give below code works great. It removes all rows except header row. So this code really t

$("#Your_Table tr>td").remove();
sid
  • 125
  • 1
  • 4
  • 11
    wait, this is jQuery answer, the original question didn't ask specifically for jQuery solution! – revelt Jul 06 '19 at 18:07
7

How about this:

When the page first loads, do this:

var myTable = document.getElementById("myTable");
myTable.oldHTML=myTable.innerHTML;

Then when you want to clear the table:

myTable.innerHTML=myTable.oldHTML;

The result will be your header row(s) if that's all you started with, the performance is dramatically faster than looping.

Len White
  • 892
  • 13
  • 25
6

this would work iteration deletetion in HTML table in native

document.querySelectorAll("table tbody tr").forEach(function(e){e.remove()})
HuntsMan
  • 762
  • 5
  • 16
6

Assing some id to tbody tag. i.e. . After this, the following line should retain the table header/footer and remove all the rows.

document.getElementById("yourID").innerHTML="";

And, if you want the entire table (header/rows/footer) to wipe out, then set the id at table level i.e.

Vinaykumar Patel
  • 864
  • 11
  • 26
3

This works in IE without even having to declare a var for the table and will delete all rows:

for(var i = 0; i < resultsTable.rows.length;)
{   
   resultsTable.deleteRow(i);
}
3

If you do not want to remove th and just want to remove the rows inside, this is working perfectly.

var tb = document.getElementById('tableId');
  while(tb.rows.length > 1) {
  tb.deleteRow(1);
}
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
3

Pure javascript, no loops and preserving headers:

function restartTable(){

const tbody = document.getElementById("tblDetail").getElementsByTagName('tbody')[0];
    tbody.innerHTML = "";

}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"/>

 <table id="tblDetail" class="table table-bordered table-hover table-ligth table-sm table-striped">
            <thead>
                <tr>
                    <th>Header 1</th>
                    <th>Header 2</th>
                    <th>Header 2</th>
                    <th>Header 2</th>
                </tr>
            </thead>
            <tbody>
              <tr>
                <td>
                  a
                </td>
                <td>
                  b
                </td>
                <td>
                  c
                </td>
                <td>
                  d
                </td>
              </tr>
              <tr>
                <td>
                  1
                </td>
                <td>
                  2
                </td>
                <td>
                  3
                </td>
                <td>
                  4
                </td>
                <tr>
                <td>
                  e
                </td>
                <td>
                  f
                </td>
                <td>
                  g
                </td>
                <td>
                  h
                </td>
               
              </tr>
              </tr>
            </tbody>
        </table>
        
                
        <button type="button" onclick="restartTable()">restart table</button>
Jaime Vasquez
  • 121
  • 1
  • 5
2

this is a simple code I just wrote to solve this, without removing the header row (first one).

var Tbl = document.getElementById('tblId');
while(Tbl.childNodes.length>2){Tbl.removeChild(Tbl.lastChild);}

Hope it works for you!!.

2

Assign an id or a class for your tbody.

document.querySelector("#tbodyId").remove();
document.querySelectorAll(".tbodyClass").remove();

You can name your id or class how you want, not necessarily #tbodyId or .tbodyClass.

Andreea
  • 21
  • 2
2

If you have far fewer <th> rows than non-<th> rows, you could collect all the <th> rows into a string, remove the entire table, and then write <table>thstring</table> where the table used to be.

EDIT: Where, obviously, "thstring" is the html for all of the rows of <th>s.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
  • 1
    Rather, collect the ``s as DOM elements, clear the table's innerHTML, then append the ``s to it again. – entonio Sep 01 '11 at 14:11
  • Beware, if you are going to replace clear tbody using the innerHTML property, it won't work in IE, there's a workaround though. – aziz punjani Sep 01 '11 at 14:31
2

This will remove all of the rows except the <th>:

document.querySelectorAll("td").forEach(function (data) {
  data.parentNode.remove();
});
Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
maryam
  • 31
  • 4
1

@lkan's answer worked for me, however to leave the first row, change

from

for (var x=rowCount-1; x>0; x--)

to

for (var x=rowCount-1; x>1; x--)

Full code:

var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>1; x--) {
   myTable.deleteRow(x);
}
Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
Neil Higgins
  • 51
  • 1
  • 8
1

Same thing I faced. So I come up with the solution by which you don't have to Unset the heading of table only remove the data..

<script>
  var tablebody =document.getElementById('myTableBody');
  tablebody.innerHTML = "";

</script>
<table>
  <thead>
  </thead>
  <tbody id='myTableBody'>
  </tbody>
</table>

Try this out will work properly...

FaizGeeky
  • 39
  • 3
0

Assuming the <table> element is accessible (e.g. by id), you can select the table body child node and then remove each child until no more remain. If you have structured your HTML table properly, namely with table headers in the <thead> element, this will only remove the table rows.

We use lastElementChild to preserve all non-element (namely #text nodes and ) children of the parent (but not their descendants). See this SO answer for a more general example, as well as an analysis of various methods to remove all of an element's children.

const tableEl = document.getElementById('my-table');

const tableBodyEl = tableEl.querySelector('tbody');

// or, directly get the <tbody> element if its id is known
// const tableBodyEl = document.getElementById('table-rows');

while (tableBodyEl.lastElementChild) {
  tableBodyEl.removeChild(tableBodyEl.lastElementChild);
}
<table id="my-table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
    </tr>
  </thead>
  <tbody id="table-rows">
    <tr>
      <td>Apple</td>
      <td>Red</td>
    </tr>
    <!-- comment child preserved -->
    text child preserved
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
    </tr>
  </tbody>
</table>
zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
0

Call replaceChildren() on the relevant element without providing options. For example:

const tableBody = document.getElementById('tableBody');
tableBody.replaceChildren();

https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren

0
var table = document.getElementById("myTable");
var rows = table.querySelectorAll("tr:not(:first-child)");
var i = rows.length - 1;

while (i >= 0) {
  table.deleteRow(i);
  i--;
}

function deleteRows() {
  const table = document.getElementById("myTable");
  const tbody = table.getElementsByTagName("tbody")[0];
  const rows = tbody.getElementsByTagName("tr");

for (let i = rows.length - 1; i >= 0; i--) {
    const row = rows[i];
    if (!row.firstChild.tagName?.includes("TH")) {
      row.parentNode.removeChild(row);
    }
  }
}
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Gender</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kareem</td>
      <td>25</td>
      <td>Male</td>
    </tr>
    <tr>
      <td>Azza</td>
      <td>30</td>
      <td>Female</td>
    </tr>
    <tr>
      <td>Mohammed</td>
      <td>40</td>
      <td>Male</td>
    </tr>
  </tbody>
</table>

<button onclick="deleteRows()">Delete Rows</button>
Kareem Adel
  • 371
  • 2
  • 10
0

Circa 2023, most browsers supported the 'unmentioned' tBodies collection. So if your TH are in rows in thead, and the rows to remove are in one or more tbodies, you can invoke, with a little iteration, table.removeChild(tbody). Needs to be tested on large tbodies.

if (table.tBodies.length > 1) console.info ('Removing more than 1 tbody element');
while (table.tBodies.length > 0) {                  // remove all tbody elements
    table.removeChild (table.tBodies[0]);
}
DWB
  • 341
  • 3
  • 6
-1

Just Clear the table body.

$("#tblbody").html("");
Bhumi Shah
  • 9,323
  • 7
  • 63
  • 104
siva
  • 17
  • 1
-3
const table = document.querySelector('table');
table.innerHTML === ' ' ? null : table.innerHTML = ' ';

The above code worked fine for me. It checks to see if the table contains any data and then clears everything including the header.

Tasos K.
  • 7,979
  • 7
  • 39
  • 63
Pope Francis
  • 557
  • 8
  • 9