Adding row to a table with Javascript - javascript

I am just doing a Javascript excercise which should add a row into a table. Html reads like this:
<!DOCTYPE html>
<html><head><br><meta charset=utf-8 />
</head><body>
<table id="sampleTable" border="1">
<tr><td>Row1 cell1</td>
<td>Row1 cell2</td></tr>
<tr><td>Row2 cell1</td>
<td>Row2 cell2</td></tr>
</table><br>
<input type="button" onclick="insert_Row()" value="Insert row">
</body></html>
And my script that doesn't work:
function insert_Row(){
var xTable=document.getElementById('sampleTable');
for (i=0;i<=xTable.children.length;i++)
{
if(i===xTable.children.length)
{
xTable.createElement('tr');
tr.innerHTML ='<td>cell1</td><td>cell2</td>'
}
}
}
This is the correct solution:
function insert_Row()
{
var x=document.getElementById('sampleTable').insertRow(0);
var y = x.insertCell(0);
var z = x.insertCell(1);
y.innerHTML="New Cell1";
z.innerHTML="New Cell2";
}
I would like to understand what is wrong with my first solution? Why doesn't it create the tag but throws error instead?

You never add the row to the table. The createElement does not attach itself to anything. You would need to use appendChild() or insertBefore()
var table = document.getElementById("sampleTable"),
tbody = table.getElementsByTagName("tbody")[0];
for (var i=0;i<5;i++) {
var row = document.createElement("tr");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
cell1.innerHTML = i + "- 1";
cell2.innerHTML = i + "- 2";
row.appendChild(cell1);
row.appendChild(cell2);
tbody.appendChild(row);
}
<table id="sampleTable" border="1">
<tbody>
<tr>
<td>Row1 cell1</td>
<td>Row1 cell2</td>
</tr>
<tr>
<td>Row2 cell1</td>
<td>Row2 cell2</td>
</tr>
</tbody>
</table>

your xTable.createElement is not creating any child element.The actual method is document.createElement().There is no element.createElement
again parentnode.children is accessing only the elements which is a direct children of table element which is tBody element.So, parentnode.children.length is equal to 1 here.But it will increase after adding another tr element as it was not added to tbody element.Thus it makes the for loop infinite.I will discuss it shortly.
also you have to use element.appendChild() method to appedn the child you
have already created.To add table cells don't use innerHTML,rather
use dom methods to do this things for you
The for loop in your code is getting infinite, because after adding one tr element to your table, xTable.children.length is increased by one.So,every time the for loop is executed it finds that the length is increased and after adding another tr element it increases once again. So,it never gets any chance to break.Thus become infinite loop.So careful when using for loop to add element to table
var xTable=document.getElementById('sampleTable');
var tr=document.createElement('tr');
tr.innerHTML ='<td>cell1</td><td>cell2</td>'
xTable.appendChild(tr);

The first error, in execution, is that you try to call xTable.createElement. Element nodes do have a createElement method; document nodes do, so you would need to use document.createElement('tr') instead. And you need to assign its return value to a variable in order to do anything with the newly created element.
Moreover, you need to add the element to the document tree. If you add it to the table, there is a problem. You have loop that traverses all the children of the table, and appending a new child would make the loop infinite. The loop is actually not needed at all. To find the last child, you need not traverse all children; you just use the children.length property. But you don’t need even that; to append a row (which is what you are doing here, not really inserting), you simply call the appendChild method of the prospective parent.
There’s more. In HTML (strictly speaking, in HTML linearization only, not in XHTML linearization), a tr element is not a child of table. Browsers will insert tbody elements when needed so that a tr is a child of a tbody which is a child of table. This means that the value of xTable.children.length is 1; the table has just one child, a tbody element.
Thus, using the approach in your first code can be properly coded as follows:
<table id="sampleTable" border="1">
<tr><td>Row1 cell1</td>
<td>Row1 cell2</td></tr>
<tr><td>Row2 cell1</td>
<td>Row2 cell2</td></tr>
</table>
<p><input type="button" onclick="insert_Row()" value="Insert row">
<script>
function insert_Row(){
var xTable = document.getElementById('sampleTable');
var tr = document.createElement('tr');
tr.innerHTML = '<td>cell1</td><td>cell2</td>';
xTable.children[0].appendChild(tr); // appends to the tbody element
}
</script>

Tables are special. They have special (optional) methods to add children. TABLE has insertRow and TR has insertCell. They're especially useful if you want to add the row/cell somewhere not at the end.
Setting a TR's innerHTML should work on most browsers, but probably not all.
(If you're building an entire table, create the HTML in JS and then set an innerHTML. It's much faster than creating separate TR and TD.)

Related

Create row in html table which does not have id and class

I would like to create one additional row in HTML Table which is very common and can be done if we have id or class available of that table.
But in my case I have one page which contains many forms and tables.
But in all those I have one form which contains only one element i.e table and I would like to create one more row and move few columns from 1st row to newly created row.
For this I have created simple HTML page.Please find below code and help me to achieve my output.
<h:form id="myForm">
<table>
<tr>
<td id="col1">Item Info</td>
<td id="col2">Description</td>
<td id="col3">Product</td>
<td id="col4">Keywords</td>
<td id="col5">Documents</td>
<td id="col6">Image</td>
<td id="col7">Video</td>
</tr>
</table>
</h:form>
Here Ia m getting output like
Item Info Description Product Keywords Documents Image Video
But I want to achieve something like below:
Item Info Description Product Keywords
NEW CELL1 Documents Image Video
means I would like to remove few columns from existing row and I would like to add it in newly created row.
For this I have written Javascript like:
<script type="text/javascript">
window.onload = function() {
split();
};
function split() {
var form = document.getElementById("myForm");
var table = form.elements[0];
var tr = document.createElement("tr");
tr.id="row2";
table.appendChild(tr);
var cell = tr.insertCell(0);
cell.innerHTML = "NEW CELL1";
var col5 = document.getElementById("col5");
tr.appendChild(col5);
var col6 = document.getElementById("col6");
tr.appendChild(col6);
var col7 = document.getElementById("col7");
tr.appendChild(col7);
}
</script>
Here, My problem is this entire form will be generated automatically so I can't give the Id for the table and with this script it is not identifying my table when I am giving form.elemets[0];
I want to find table element so that I can create row in that table.
You can find the table by doing this:
Get one of the elements in a table row, and get the parent node until you've got the table. In this case you could do document.getElementById('col1').parentNode.parentNode
And just to ease things,
You can insert this string '</tr><tr>' in a row, after a table cell, to easily create a new row.
This should be better than document.getElementsByTagName('table'), because if you have lots of tables which are far away, it will take more time to find your table's index in that array.
Use getElementsByTagName to get the table from within your form, which has an ID
window.onload = function() {
split();
};
function split() {
var form = document.getElementById("myForm");
var table = form.getElementsByTagName("table")[0];
var tr = document.createElement("tr");
tr.id = "row2";
table.appendChild(tr);
var cell = tr.insertCell(0);
cell.innerHTML = "NEW CELL1";
/*Your original code produces duplicate IDs which is a BAD thing*/
var col5 = document.getElementById("col5");
/*Update new Id*/
col5.id += "_new";
tr.appendChild(col5);
var col6 = document.getElementById("col6");
/*Update new Id*/
col6.id += "_new";
tr.appendChild(col6);
var col7 = document.getElementById("col7");
/*Update new Id*/
col7.id += "_new";
tr.appendChild(col7);
}
<form id="myForm">
<table>
<tr>
<td id="col1">Item Info</td>
<td id="col2">Description</td>
<td id="col3">Product</td>
<td id="col4">Keywords</td>
<td id="col5">Documents</td>
<td id="col6">Image</td>
<td id="col7">Video</td>
</tr>
</table>
</form>
You also have a mismatch of column numbers, with the code provided you originally have 7 columns and only insert 4, this will produce inconsistent results, make sure to use the colspan attribute as needed.
You should be able to use JavaScript's querySelector method to select the table data you want to remove from the document.
Something like var rowToDeleteOrAddTo = document.querySelector("#myForm > table > tr > td"); should help you get there. You'll need to lookup CSS Selectors to get the specific selectors you need. You may need to use the textContent property once you have a node to make sure you are deleting the right one.

Get back to a reference of a tr

I've got something to the effect of this:
<table>
<tr>
<td></td>
<td></td>
<td>
<table>
<tr>
<td>click me</td>
</tr>
</table>
</td>
</tr>
...
</table>
I have a click event in jquery for my anchor tag with class "fav":
$(".fav").click(function(){
var parentRow = $(this).closest('tr');
});
This gives me a reference to the tr within my 2nd table (the table within the td). I'd like to get a reference back to the tr in my initial table. Pictured highlight shows where I have a reference. Arrow shows where I'd like to get a reference.
There are plenty of other tables on the page.
You can use .parents( selector ) function:
$(".fav").click(function(){
var parentRow = $(this).parents("tr:eq(1)");
// or $(this).parents("tr").eq(1);
// or $($(this).parents("tr")[1]);
// or $($(this).parents("tr").get(1));
});
Well, you are selecting the closest TR, which is the one in the inner table. To get the closest TR in the outer table, you have to find that outer table first:
$(".fav").click(function(){
var parentRow = $(this).closest('table').closest('tr');
});
Just find the <tr> that is a parent. CodePen
$(".fav").click(function(){
var parentRow = $(this).closest('tr').parents('tr')[0];
console.log(parentRow)
});
use this:
var parentRow = $(this).closest('table').closest('tr');

Dynamically create div inside table using jQuery?

I am creating a div dynamically in jQuery as mentioned in the below code appending to the form.
var temp = document.createElement("div");
temp.setAttribute("id", "test");
Form:
<form id="test1" method="get">
</form>
I am trying to have a table created dynamically and need to have this inside a table?
To form table dynamically:
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test").prepend(tableHeader);
Now I need to have <td> (Which I need to create) inside which I need the div element I created. Like this:
<table>
...
....
<tr>
<td>
<div id="test"> // Div i created dynamically in the top(1st line)
</div>
</td>
</tr>
How do I achieve this in jQuery?
Why don't you create the table first?
and then append the table into the dom.
give an id to the td where you want to insert your div.
$('#td-id').html({div-content-goes-here}).
the html() function puts its contents inside the selected dom node.
you can also use append(),
Try the below code:
var temp = document.createElement("div");
temp.setAttribute("id", "test");
console.log(temp);
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$('body').append(tableHeader);
$('table').append(temp);
Also check this JSFiddle and share your thoughts.
To append the div to the td of the table, you must first have such a td. The code below checks its existence and adds it if it doesn't exist.
<form id="test1" method="get"></form>
JavaScript:
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test1").prepend(tableHeader);
if ($('#test1 table tr td:first-child').size()==0) {
console.log('Table has no TDs. Creating a row.');
$('#test1 table tbody').append('<tr><td></td><td></td><td></td></tr>');
}
var temp = document.createElement("div");
temp.setAttribute("id", "test");
temp.appendChild(document.createTextNode('test Div Inserted'));
// appends the DIV to the first TD of the TABLE under #test1 FORM
$('#test1 table tr td:first-child').append(temp);
JSFiddle Demo.
#user2067567, here is a healthy approach, put an id on your dynamic table, before you append it to the DOM...
var tableHeader = '<table border="1" id="mtableid"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
...Then make your base point for manipulating your new table from this ID...
var mtable = $('#mtableid');
...Then look for the tr row you want to enter...
var firstrow = mtable.find('tr').eq(1);
...Then append content to the first row...
$('<td><div>...</div></td>').appendTo(firstrow);
This is all untested, but posted just to give you a general idea.
Let me know if you want further details.
var temp = document.createElement("div");
temp.setAttribute("id", "test");
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test1").prepend(tableHeader);
$('tr').append(temp);
$('div').html('create div content');
the answer to your question is quite simple but there is an important point that you've missed to explain. Which tr do you want to append to. Do you want to create a new tr for every div you want to append to the table or is there some other logic?

How to make a table with rows that can be copied (adding a new row after that one, containing the same) with Javascript?

I am trying to make a table containing several rows, each with a button in the last cell that creates a copy of the row.
All the other cells contains an input (text).
The content (value) of the inputs that are added must be the same as the one above (the one they are copies of).
The copies cannot be copied however!
The inputs must have a unique name something like this:
1-1-name
1-1-age
1-1-country
1-1-email
and if this row is copied, the copied inputs must have names like this
1-2-name
1-2-age
1-2-country
1-2-email
The next one with 3 instead of 2, and so on.
The problem with this, I guess, is that I must do this without JQuery. I can only use Javascript. Is this even possible?
Take a look at this fiddle. Here is a pure js (no-jQuery) way to duplicate a table row and increment it's ID:
var idInit;
var table = document.getElementById('theTable');
table.addEventListener('click', duplicateRow); // Make the table listen to "Click" events
function duplicateRow(e){
if(e.target.type == "button"){ // "If a button was clicked"
var row = e.target.parentElement.parentElement; // Get the row
var newRow = row.cloneNode(true); // Clone the row
incrementId(newRow); // Increment the row's ID
var cells = newRow.cells;
for(var i = 0; i < cells.length; i++){
incrementId(cells[i]); // Increment the cells' IDs
}
insertAfter(row, newRow); // Insert the row at the right position
idInit++;
}
}
function incrementId(elem){
idParts = elem.id.split('-'); // Cut up the element's ID to get the second part.
idInit ? idParts[1] = idInit + 1 : idInit = idParts[1]++; // Increment the ID, and set a temp variable to keep track of the id's.
elem.id = idParts.join('-'); // Set the new id to the element.
}
function insertAfter(after, newNode){
after.parentNode.insertBefore(newNode, after.nextSibling);
}​
<table id="theTable">
<tr id="1-1">
<td id="1-1-name"><input type="text"/></td>
<td id="1-1-age"><input type="text"/></td>
<td id="1-1-country"><input type="text"/></td>
<td id="1-1-email"><input type="text"/></td>
<td id="1-1-button"><input type="button" value="Copy"/></td>
</tr>
</table>​
Edit: Updated to insert the new row after the clicked one. Now with buttons and inputs!
Yes this is possible,
you should create a new table row ,
then set its innerHTML to the innerHTML of the row above.
jQuery is a JavaScript library, which means it is built with JavaScript functions.
So everything you can do with jQuery, you can do with JavaScript too.
Léon

Delete all rows in an HTML table

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
this will remove all the rows:
$("#table_of_items tr").remove();
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)
Very crude, but this also works:
var Table = document.getElementById("mytable");
Table.innerHTML = "";
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.
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!
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);
}
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!
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);
}
the give below code works great.
It removes all rows except header row. So this code really t
$("#Your_Table tr>td").remove();
this would work iteration deletetion in HTML table in native
document.querySelectorAll("table tbody tr").forEach(function(e){e.remove()})
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.
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.
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);
}
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>
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.
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);
}
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!!.
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.
#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);
}
This will remove all of the rows except the <th>:
document.querySelectorAll("td").forEach(function (data) {
data.parentNode.remove();
});
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...
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>
Just Clear the table body.
$("#tblbody").html("");
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.

Categories