views:

78644

answers:

12

What is the best method in jQuery to add an additional row to a table as the last row?

+4  A: 

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)?

Darryl Hein
That should work.You can add as much you want.
Eikern
+76  A: 

The approach you suggest is not guaranteed to give you the result you're looking for - what if you had a tbody for example:

<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>');
Luke Bennett
Does this work if there are no rows in the table?
Rama Vadakattu
@Rama, no it won't. There needs to be a better solution.
Floetic
I accept this, but the OP did speak about adding an "additional row" which implies the table already contains other rows, so I'm not sure you'd need to modify the solution any more to answer this particular question.
Luke Bennett
There will always be a tbody in the DOM.
eyelidlessness
eyelidlessness (great name!) that's a good point and one I hadn't appreciated. I am updating my answer in light of this.
Luke Bennett
Why wouldn't you put an id on the tbody to stop the need for the #myTable > tbody selection?
Gareth Simpson
@Gareth, you could do just that. But this approach will still work when you don't specify a tbody in your markup (because it will still exist in the DOM). Therefore it's a bit more reusable.
Luke Bennett
an empty tbody does not validate your html though
2ni
The $('#myTable > tbody:last').append version seems to reverse the order of the table rows.
rsrobbins
+16  A: 

what if you had a tbody for example

Well, 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>");
DaRKoN_
You have implemented your tfoot incorrectly. It should come before the tbody, not after - see http://www.w3.org/TR/html4/struct/tables.html#h-11.2.3. Therefore my solution still works unless you choose to break the standards (in which case you can expect other things to go wrong as well).My solution also works whether you have a tbody or not, whereas your proposal will fail if a tbody is not present.
Luke Bennett
Despite any mistakes in the <tfoot />, this is a better solution. If there is no <tbody /> you can use the same technique on the <table /> itself. Whereas the "accepted answer" requires an additional check to see whether or not there is an existing row. (I know the OP didn't specify this requirement, but it doesn't matter -- this post comes up 1st on a Google search for this technique, and the best answer is not the top.)
Clever Human
+2  A: 

You 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.

Here is an example usage:

// One table
addTableRow($('#myTable'));
// add table row to number of tables
addTableRow($('.myTables'));
Uzbekjon
I can't see that being terribly useful. All it does is add an empty table row to a table. Typically, if not always, you want to add a new table row with some data in it.
Darryl Hein
But that is usually what you want. This function lets you add en empty row to any of your tables, no matter how many columns and row spans you have, thus making it UNIVERSAL function. You can carry on from there for example with $('.tbl tr:last td'). The whole point is to have universal function!!!
Uzbekjon
If your function also adds data into your new rows, you will not be able to use it the next time on your next project. What is the point?!It is in my opinion though, you don't need to share it...
Uzbekjon
A: 

How about when we add another features like having a datepicker to the input field in that table cell? Mine is not working currently... I use jquery.tables and jquery.datepicker in the same table... any help?

+27  A: 

JQuery has a built-in facility to manipulate DOM elements on the fly.

You can add anything to your table like this:

$("#tableClassname").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.

Neil
I'd have to say this is probably the best answer on this question.
HorusKol
For those who are trying this, note carefully the locations of the parentheses. Proper nesting is crucial.
Kyralessa
A: 

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.

$('#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);
Avron Olshewsky
Missing HTML is <tr id="row1"> </tr><tr id="row2"> </tr>so on ..
Avron Olshewsky
I think this should be a new question, instead of an answer to an existing one...
Darryl Hein
+1  A: 

This can be done easily using the "last()" function of jQuery.

$("#tableId").last().append("<tr><td>New row</td></tr>");
Nischal
Good idea, but I think you'd want to change the selector to #tableId tr as right now you'd get the table add the row below the table.
Darryl Hein
Thanks for it....
Karandeep Singh
+2  A: 

FYI - Avoid using multiple appends (slows down performance tremendously), rather build up your string or use JQuery join which is much faster.

Grep
A: 
$('table#tbl_sel_drug > tbody > tr:gt(1)').not(':last').remove();

Dude This can solve your problem for deleting all rows except first and last.

Best of luck!!!!

VIPUL DADHICH
Huh? This question was about adding a table row, not removing them.
Darryl Hein
A: 

I know this is an old post but I was struggling and the answer given here didn't help so I thought I'd post my answer it might help others searching for this...

 $('<tr>...Insert Data ...</tr>').insertAfter("table#editorRows > tbody > tr:last");

Worked a treat ;)

Andyroo
That is another method.
Darryl Hein
+2  A: 

I recommend

$('#myTable > tbody:first').append('<tr>...</tr><tr>...</tr>'); 

to oppose 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>
Curtor