What is the best method in jQuery to add an additional row to a table as the last row?
Update
Is this acceptable:
$('#myTable').append('<tr><td>my data</td><td>more data</td></tr>');
Are there limitations to what you can add to a table like this (such as inputs, selects, number of rows)?
Source: Tips4all
The approach you suggest is not guaranteed to give you the result you're looking for - what if you had a tbody for example:
ReplyDelete<table id="myTable">
<tbody>
<tr>...</tr>
<tr>...</tr>
</tbody>
</table>
You would end up with the following:
<table id="myTable">
<tbody>
<tr>...</tr>
<tr>...</tr>
</tbody>
<tr>...</tr>
</table>
I would therefore recommend this approach instead:
$('#myTable tr:last').after('<tr>...</tr><tr>...</tr>');
You can include anything within the after() method as long as it's valid HTML, including multiple rows as per the example above.
Update: Revisiting this answer following recent activity with this question. eyelidlessness makes a good comment that there will always be a tbody in the DOM; this is true, but only if there is at least one row. If you have no rows, there will be no tbody unless you have specified one yourself.
DaRKoN_ suggests appending to the tbody rather than adding content after the last tr. This gets around the issue of having no rows, but still isn't bulletproof as you could theoretically have multiple tbody elements and the row would get added to each of them.
Weighing everything up, I'm not sure there is a single one-line solution that accounts for every single possible scenario. You will need to make sure the jQuery code tallies with your markup.
I think the safest solution is probably to ensure your table always includes at least one tbody in your markup, even if it has no rows. On this basis, you can use the following which will work however many rows you have (and also account for multiple tbody elements):
$('#myTable > tbody:last').append('<tr>...</tr><tr>...</tr>');
jQuery has a built-in facility to manipulate DOM elements on the fly.
ReplyDeleteYou can add anything to your table like this:
$("#tableID").find('tbody')
.append($('<tr>')
.append($('<td>')
.append($('<img>')
.attr('src', 'img.png')
.text('Image cell')
)
)
);
The $('<some-tag>') thing in jQuery is a tag object that can have several attr attributes that can be set and get, as well as text, which represents the text between the tag here: <tag>text</tag>.
This is some pretty weird indenting, but it's easier for you to see what's going on in this example.
what if you had a tbody for example
ReplyDeleteWell, what if you had a tfoot? such as:
<table>
<tbody>
<tr><td>Foo</td></tr>
</tbody>
<tfoot>
<tr><td>footer information</td></tr>
</tfoot>
</table>
Then it would insert your new row in the footer - not to the body.
Hence the best solution is to include a <tbody> tag and use .append, rather than .after.
$("#myTable > tbody").append("<tr><td>row content</td></tr>");
I recommend
ReplyDelete$('#myTable > tbody:first').append('<tr>...</tr><tr>...</tr>');
as opposed to
$('#myTable > tbody:last').append('<tr>...</tr><tr>...</tr>');
The first and last keywords work on the first or last tag to be started, not closed. Therefore, this plays nicer with nested tables, if you don't want the nested table to be changed, but instead add to the overall table. At least, this is what I found.
<table id=myTable>
<tbody id=first>
<tr><td>
<table id=myNestedTable>
<tbody id=last>
</tbody>
</table>
</td></tr>
</tbody>
</table>
This can be done easily using the "last()" function of jQuery.
ReplyDelete$("#tableId").last().append("<tr><td>New row</td></tr>");
FYI - Avoid using multiple appends (slows down performance tremendously), rather build up your string or use JavaScript join which is much faster.
ReplyDeleteYou can use this great jQuery add table row function. It works great with tables that have <tbody> and that don't. Also it takes into the consideration the colspan of your last table row.
ReplyDeleteHere is an example usage:
// One table
addTableRow($('#myTable'));
// add table row to number of tables
addTableRow($('.myTables'));
I'm using this way when there is not any row in the table, as well as, each row is quite complicated.
ReplyDeletestyle.css:
...
#templateRow {
display:none;
}
...
xxx.html
...
<tr id="templateRow"> ... </tr>
...
$("#templateRow").clone().removeAttr("id").appendTo( $("#templateRow").parent() );
...
I know you have asked for a Jquery Method.
ReplyDeleteI looked a lot and find that We can do it in a more better way using javascript directly by following function.
tableObject.insertRow(index)
index is An integer that specifies the position of the row to insert (starts at 0). The value of -1 can also be used; which result in that the new row will be inserted at the last position.
This parameter is required in Firefox and Opera, but optional in Internet Explorer, Chrome and Safari.
If this parameter is omitted, insertRow() inserts a new row at the last position in IE and at the first position in Chrome and Safari.
It will work for every acceptable structure of HTML table.
Following Example will insert a row in last (-1 is used as index):
<html>
<head>
<script type="text/javascript">
function displayResult()
{
document.getElementById("myTable").insertRow(-1).innerHTML = '<td>1</td><td>2</td>';
}
</script>
</head>
<body>
<table id="myTable" border="1">
<tr>
<td>cell 1</td>
<td>cell 2</td>
</tr>
<tr>
<td>cell 3</td>
<td>cell 4</td>
</tr>
</table>
<br />
<button type="button" onclick="displayResult()">Insert new row</button>
</body>
</html>
Hope it Helps
An old post, but with best solution posted, if there's a nested table on the last row, the new row will be added to the nested table instead of the main table. A quick solution (considering tables with/without tbody and tables with nested tables):
ReplyDeletefunction add_new_row(table,rowcontent){
if ($(table).length>0){
if ($(table+' > tbody').length==0) $(table).append('<tbody />');
($(table+' > tr').length>0)?$(table).children('tbody:last').children('tr:last').append(rowcontent):$(table).children('tbody:last').append(rowcontent);
}
}
Usage example:
add_new_row('#myTable','<tr><td>my new row</td></tr>');
I was having some related issues, trying to insert a table row after the clicked row. All is fine except the .after() call does not work for the last row.
ReplyDelete$('#traffic tbody').find('tr.trafficBody).filter(':nth-child(' + (column + 1) + ')').after(insertedhtml);
I landed up with a very untidy solution:
create the table as follows (id for each row):
<tr id="row1"> ... </tr>
<tr id="row2"> ... </tr>
<tr id="row3"> ... </tr>
etc ...
and then :
$('#traffic tbody').find('tr.trafficBody' + idx).after(html);
I found this AddRow plugin quite useful for managing table rows. Though, Luke's solution would be the best fit if you just need to add a new row.
ReplyDeleteA bit late to the party but here's my solution.
ReplyDelete//Adds a new table row
$.fn.addNewRow = function (rowId) {
$(this).find('tbody').append('<tr id="' + rowId + '"> </tr>');
};
usage:
$('#Table').addNewRow(id1);
<table id=myTable>
ReplyDelete<tr><td></td></tr>
<style="height=0px;" tfoot></tfoot>
</table>
You can cache the footer variable and reduce access to DOM (Note: may be it will be better to use a fake row instead of footer).
var footer = $("#mytable tfoot")
footer.before("<tr><td></td></tr>")
$('#myTable').append('<tr><td>my data</td><td>more data</td></tr>');
ReplyDeletewill add a new row to the first TBODY of the table, without depending of any THEAD or TFOOT present.
(I didn't find information from which version of jQuery .append() this behavior is present.)
You may try it in these examples:
<table class="t"> <!-- table with THEAD, TBODY and TFOOT -->
<thead>
<tr><th>h1</th><th>h2</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td></tr>
</tbody>
<tfoot>
<tr><th>f1</th><th>f2</th></tr>
</tfoot>
</table><br>
<table class="t"> <!-- table with two TBODYs -->
<thead>
<tr><th>h1</th><th>h2</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td></tr>
</tbody>
<tbody>
<tr><td>3</td><td>4</td></tr>
</tbody>
<tfoot>
<tr><th>f1</th><th>f2</th></tr>
</tfoot>
</table><br>
<table class="t"> <!-- table without TBODY -->
<thead>
<tr><th>h1</th><th>h2</th></tr>
</thead>
</table><br>
<table class="t"> <!-- table with TR not in TBODY -->
<tr><td>1</td><td>2</td></tr>
</table>
<br>
<table class="t">
</table>
<script>
$('.t').append('<tr><td>a</td><td>a</td></tr>');
</script>
In which example a b row is inserted after 1 2, not after 3 4 in second example. If the table were empty, jQuery creates TBODY for a new row.