Si Stone
Si Stone

Reputation: 121

JQuery Datatables reloading data with child rows

I am trying to replicate the functionality shown here:

JQuery Datatables - Child Rows

This works perfectly using the code shown below:

function format ( d ) {
// `d` is the original data object for the row
return '<table class="table table-bordered" cellpadding="5" cellspacing="0" border="1" style="padding-left:50px;">'+
    '<tr>'+
        '<td width="100px" style="padding:3px"><strong>Assigned To:</strong></td>'+
        '<td style="padding:3px">'+d.assignedto+'</td>'+
    '</tr>'+
    '<tr>'+
        '<td style="padding:3px"><strong>Area:</strong></td>'+
        '<td style="padding:3px">'+d.area+'</td>'+
    '</tr>'+
    '<tr>'+
        '<td style="padding:3px"><strong>Category:</strong></td>'+
        '<td style="padding:3px">'+d.category+'</td>'+
    '</tr>'+
    '<tr>'+
        '<td style="padding:3px"><strong>Notes:</strong></td>'+
        '<td style="padding:3px">'+d.notes+'</td>'+
    '</tr>'+
'</table>';
$(document).ready(function() {
$( "#btn-getorder" ).click( function(event) {
    var table = $('#tbl-l250-tickets').DataTable( {
        retrieve: true,
        "ajax": "ajax-get-last250tickets.php?cust-code="+$("#hid-cust-id").val(),
        "columns": [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data": "ticketid" },
            { "data": "orderno" },
            { "data": "issue" },
            { "data": "receiveddate" },
            { "data": "completeddate" },
            { "data": "notesshort" }
        ]
    } );

    // Add event listener for opening and closing details
    $('#tbl-l250-tickets tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( format(row.data()) ).show();
            tr.addClass('shown');
        }
    } );
});

});

The problem I have is, if a new order number is entered, and the page is regenerated with new data, the child row expansion is failing with 'd is undefined' in the 'format' function.

Having stepped through the code, it looks as though the 'row' variable is empty when the format function is called on the new table. It works for the first order loaded into the page, but fails for any subsequent.

I don't understand why this should be the case.

I have also tried explicitly destroying the table with the following:

if ( $.fn.dataTable.isDataTable( '#tbl-l250-tickets' ) ) {
        table = $('#tbl-l250-tickets').DataTable();
        table.destroy();
    };

before the table is re-created, but this hasn't helped either.

Any ideas?

Upvotes: 0

Views: 1551

Answers (1)

Gyrocode.com
Gyrocode.com

Reputation: 58860

You're attaching event handler for td.details-control every time user clicks #btn-getorder.

Try detaching the handler first:

// Detach event listener
$('#tbl-l250-tickets tbody').off('click', 'td.details-control');

// Add event listener for opening and closing details
$('#tbl-l250-tickets tbody').on('click', 'td.details-control', function () {
   // ... 
});

Even better solution would be to move event handler outside of the click event handler for #btn-getorder.

$(document).ready(function() {
   $( "#btn-getorder" ).click( function(event) {
      // ... 
   });

   // Add event listener for opening and closing details
   $('#tbl-l250-tickets tbody').on('click', 'td.details-control', function () {
      // ... 
   });
});

Upvotes: 1

Related Questions