Skip to content Skip to sidebar Skip to footer

Why Doesn't Columns.render Execute When Datatable().draw() Is Called?

I'm puzzled to why columns.render is not included in the execution pipeline of DataTable().draw(). An example: HTML

Solution 1:

Instead of destroying the datatable and repopulating it I ended up modifying jquery.datatables.js version 1.10.2.

The main issue is that the line 1935 in jquery.datatables.js checks if the row is already created:

if ( aoData.nTr === null )
{
  _fnCreateTr(oSettings, iDataIndex);
}

One option to remedy this is to set aoData.nTr = null. But this might break other functionality or cause unwanted side effects so this is not an acceptable solution.

I opted to instead add an argument to the .draw() function (line 7137) and adding a setting called bForceReDraw (draw() already takes an argument so we add a second argument):

_api_register('draw()', function (resetPaging, forceReDraw) {
  returnthis.iterator( 'table', function ( settings ) {
    settings.bForceReDraw = forceReDraw === true;
      _fnReDraw(settings, resetPaging === false);
  } );
} );

Then I changed the null check on line 1935 to:

if ( aoData.nTr === null || oSettings.bForceReDraw === true )
{
  _fnCreateTr(oSettings, iDataIndex);
}

In the function _fnCreateTr() there is also a null check on nTr (line 1586) so I needed to modify that as well:

if ( row.nTr === null || oSettings.bForceReDraw === true )
{
  nTr = nTrIn || document.createElement('tr');
  ...

Now we simply call draw() with the new argument and everything works as expected.

$('#data').DataTable().columns.adjust().draw(false, true);

Solution 2:

Everybody has problems dynamically reloading DataTables. Consider this approach. Destroy the DataTable first to re-render.

var dataSet = [];

if ($.fn.dataTable.isDataTable('#yourTable')) {
    $('#yourTable').DataTable({
        "destroy": true,
        "processing": true,
        "data": dataSet
    });
} else {
    $('#yourTable').DataTable({
        "processing": true,
        "data": dataSet
    });
}

Solution 3:

I found that, contrary to .draw(), .columns.adjust().draw(); will fire the render function again. But, unfortunately, it doesn't re-render the table... (?)

The only workaround I found is to .destroy() the table, replace $('#data').html() with its original contents and start again with $('#data').DataTable({ columnDefs: colDefs });.

$(document).ready(function () {
    var table_data = $('#data').html();

    var colRender = function (data, type, row, meta) {
        var today = newDate();
        var ms = today.getMilliseconds();
        var ss = today.getSeconds();
        var mn = today.getMinutes();
        var hh = today.getHours();
        var time = ' time:' + hh + ':' + mn + ':' + ss + ':' + ms
        console.log('data+time', data + time);
        return data + time;
    }

    var colDefs = [{
        targets: 0,
        render: colRender
    }];
    
    $('#data').DataTable({
        columnDefs: colDefs
    });

    $('#refresh').click(function () {
        // $('#data').DataTable().columns.adjust().draw();// $('#data').DataTable().draw();
        $('#data').DataTable().destroy();
        $('#data').html(table_data);
        $('#data').DataTable({
            columnDefs: colDefs
        });
    });
});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><scriptsrc="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script><linkhref="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css"rel="stylesheet"/><tableid="data"><thead><tr><th>TimeColumn</th><th>Column 2</th></tr></thead><tbody><tr><td>123</td><td>234</td></tr><tr><td>345</td><td>456</td></tr><tr><td>567</td><td>678</td></tr></tbody></table><buttonid="refresh">Refresh</button>

Post a Comment for "Why Doesn't Columns.render Execute When Datatable().draw() Is Called?"