Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

<table id="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>

<button id="refresh">Refreh</button>

jQuery

$(document).ready(function () {
    $('#data').DataTable({
        columnDefs: [{
            targets: 0,
            render: function(data, type, row, meta) {
                return data + ' time:' + Date.now();
            }
        }]
    });

    $('#refresh').on('click', function() {
        $('#data').DataTable().draw();
    });
});

The expected result when clicking the Refresh button is that the time value should advance in the first column, but it doesn't.
The assigned render function is never called after initialization.

(jsFiddle of the example.)

Is there any workaround or do I have to dig into the code of DataTables?

like image 834
Sani Singh Huttunen Avatar asked Sep 18 '14 21:09

Sani Singh Huttunen


People also ask

What is render in Datatable?

render which can be used to process the content of each cell before the data is used. columns. render has a wide array of options available to it for rendering different types of data orthogonally (ordering, searching, display etc), but it can be used very simply to manipulate the content of a cell, as shown here.

What is draw in Datatable server-side?

The draw parameter is only used by DataTables to ensure that the Ajax returns from server-side processing requests are drawn in sequence by DataTables.

What is draw parameter DataTables?

The draw parameter (server-side processing) is just a sequence counter. It allows responses to come back out of order and DataTables will draw the correct page. For example: Draw=1 requested.

Can we use Datatable with Div?

DataTables places the main table and all of the various component display controls for the table inside a container element, a div element with a class of dataTables_wrapper (by default).


1 Answers

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) {
  return this.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);
like image 77
Sani Singh Huttunen Avatar answered Nov 08 '22 06:11

Sani Singh Huttunen