Skip to content

Append to a table when tbody is absent and how to make all existing jqueries work for that row

I have the following jquery to append to a table dynamically based on user interaction and data received from the server. Now each column in the table has some specific class and some style attributes like the column itemId is hidden and so on. My dynamic addition is working fine if I already have one row but if its none it just adds another header row which I can understand is because my code copies the last tr element. Question is how do I go about adding a row to ‘tbody’ when their are no rows.

    function responseTopicAdded(data) {
        $('#dialog-modal').dialog('close');
        rowcopy = $('#datatable tr:last').clone();
        rowcopy.children().each(function() {
            switch($(this).attr('class')) {
                case 'Name':
                    $(this).html(data.Name);
                    break;
                case 'Description':
                    $(this).html(data.Description);
                    break;
                case 'Icon':
                    $(this).html('<img src='+ data.Icon +'/>');
                    break;
                case 'itemId':
                    $(this).html(data.itemId);
            }
        });
        $('#datatable tr:last').after($(rowcopy));
    }

My second question is that my table cells respond to a double click. But the newly added row never responds (even when there are previous rows and the row is added normally).

Why doesn’t the listener work on the new row?

My listener goes like this:

$(document).ready(function() {
    try {
        $("td").dblclick(function() {
            // ... my code goes here
    }catch(a){
        alert(a);
    }
}

Answer

You can go with template approach to create a template for your table row to be cloned when required.

Say your table is this:

<table id="datatable">
    <thead>
          <tr><th>Name</th>
          <th>Description</th>
          <th>icon</th>
          <th>itemID</th></tr>
    </thead>
   <tbody></tbody>
</table>

When you populate:

//Create the template here// or keep it in HTML itself in a hidden div or something.
var template = $("<tr><td class='Name'></td><td class='Description'></td><td class='Icon'></td><td class='itemId'></td></tr>");

$(function () {

var newRow = $(template).clone(); //Clone the template

//just an initial load
newRow.find('.Name').text('AAA');
newRow.find('.Description').text('Some Description');
newRow.find('.Icon').text('Some Icon');
newRow.find('.itemId').text('1234');

//Initially clone
$('#datatable').find('tbody').append(newRow);

    //register the handler using event delegation
    $('#datatable tbody').on('click', 'tr', function () {
        alert('clicked on ' + $(this).find('.Name').text());
    });

    $('#addNew').on('click', function () {
        var rowcopy = $(template).clone(); //Clone the template
        var data = {
            Name: 'BBB',
            Description: 'Some Description',
            Icon: 'http://placehold.it/32x32',
            itemId: '45676'
        };

       //Set the Css class name based on even odd row
       rowcopy.addClass(function(){
        return $('#datatable tbody tr').length % 2 == 0 ? "odd" : "even";
       });

        rowcopy.children().each(function () {
            switch ($(this).attr('class')) {
                case 'Name':
                    $(this).html(data.Name);
                    break;
                case 'Description':
                    $(this).html(data.Description);
                    break;
                case 'Icon':
                    $(this).html('<img src=' + data.Icon + '/>');
                    break;
                case 'itemId':
                    $(this).html(data.itemId);
            }
        });
        $('#datatable tbody').append($(rowcopy)); //Append it to the tbody.
    });

});

Demo

For adding even/odd styles you can use css itself.

#datatable tbody tr:nth-child(odd) {
    background-color:#cecece;
}
#datatable tbody tr:nth-child(even) {
    background-color:yellow;
}

If not you want to do it with the class then:

rowcopy.addClass(function(){
            return $('#datatable tbody tr').length % 2 == 0 ? "odd" : "even";
});

Demo