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?
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.
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.
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.
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).
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With