Datatables table loads twice, first time without table data

Datatables table loads twice, first time without table data

basejumperbasejumper Posts: 6Questions: 0Answers: 0
edited September 2011 in DataTables 1.8
Hello! I'm having one strange thing with datatables table: it loads twice, first time for a very short period of time (less than one sec.) without data from database (showing message defined in sZeroRecords argument (Haven't found any record!) - looks like it tries to search for something and doesn't find it), second time it loads normally. Maybe my program tries to load table data before it loads Ajax source. I tried to put an alert within fnDrawCallback (alert(oSettings.aiDisplay.length);) ; it displays two times (firstly - 0 then - 47, correct table record count). It doesn't disturb me very much because within a second, maybe even less, correct data is being shown. I just want to know is it my personal error due to lack of knowledge or something more global. Help me please if you have any ideas about this issue. P.S. I'm using presently the last version of datatables (1.8.2). You can see my code below:

$(document).ready(function() {
"fnDrawCallback": function ( oSettings ) {


/*Highlighting selected row*/
$('td').bind('mouseenter', function () { $(this).parent().children().each(function(){$(this).addClass('datatablerowhighlight');}); });
$('td').bind('mouseleave', function () { $(this).parent().children().each(function(){$(this).removeClass('datatablerowhighlight');}); });

/*Adding classes depending on sending state*/
$("tr:contains('waiting')").addClass ('waiting');
$("tr:contains('error')").addClass ('error');
$("tr:contains('cancelled')").addClass ('cancelled');

$('DIV.bottom').addClass('fg-button ui-widget-header ui-corner-bottom');
$('').addClass('fg-button ui-widget-header ui-corner-top');


"bProcessing": false,
"bJQueryUI": true,
"oLanguage": {
"sLengthMenu": "_MENU_",
"sInfo": "Records from _START_ to _END_. Total: _TOTAL_ ",
"sZeroRecords": "Haven't found any record!",
"sInfoEmpty": "Empty table information!",
"sInfoFiltered": "Records filtred!",
"sSearch":"Search all columns:",
"oPaginate": {
"sFirst": "First",
"sPrevious": "Previous",
"sNext": "Next",
"sLast": "Last"
"sPaginationType": "full_numbers",
"sDom": '<"top"flpi<"clear">>rt<"bottom"lpi<"clear">>',
"bAutoWidth": true,
"bServerSide": false,
"bStateSave": true,
"sAjaxSource": "getdata.php",
"aoData": [

/* check */{
"bSortable": false,
"bSearchable": false,
"sClass": "center"
/* status */{
"bSearchable": true,
"sClass": "center"
/* id */ {
"bSearchable": true,
"sClass": "center"
/* email */{
"bSearchable": true,
"sClass": "center"



Server side code:
$dbQuery = "SELECT `id`, `email`, `status` FROM `addresses` WHERE `status` <> 'sent'";

$query = execQuery($dbQuery, "object");

$sOutput = '{';
$sOutput .= '"aaData": [ ';

while($result = $query->fetch_assoc()){

$sOutput .= "[";
$sOutput .= ($result["status"] == "error") ? '"",' : '"",';
$sOutput .= '"' . str_replace('"', '/"', $result["status"]) . '",';
$sOutput .= '"' . str_replace('"', '/"', $result["id"]) . '",';
$sOutput .= '"' . str_replace('"', '/"', $result["email"]) . '"';
$sOutput .= "],";


$sOutput = substr_replace($sOutput, "", -1);
$sOutput .= '] }';

echo $sOutput;


  • GregPGregP Posts: 487Questions: 8Answers: 0
    Based on visual inspection, the first time it's being fired is when you set oTable variable within your function; the second is when you then call that 'getDatatable()' function. Or it could be that one of those is when you redeclare oTable as datatable. Not 100% sure, but certainly there is redundancy in the way you're creating and caching the table, and that's where your problems stem from.

    The way you've set up your caching is not necessary; just put the whole "var oTable = $('#katalog').dataTable({ ... })" block into the document ready function, and Bob's your uncle!
  • basejumperbasejumper Posts: 6Questions: 0Answers: 0
    GregP thank you for your advice, but I've already tried it. Unfortunately it doesn't change situation: loading still happens twice :(
  • GregPGregP Posts: 487Questions: 8Answers: 0
    did you get rid of 'datatable = oTable' also? Since you're not even using the datatable variable anywhere, that's a safe one.

    I wonder if the filter is getting triggered? The handler itself seems fine, but is it possible that it's getting fired somehow?
  • basejumperbasejumper Posts: 6Questions: 0Answers: 0
    I'm using this variable to call datatables methods (for example fnReloadAjax() or fnAdjustColumnSizing()) from other functions (I set oTable to some other variable datatable, declared globally, so I can use it globally, it was very usefull to automatically reload datatable in Ajax callback after data have been modified ). I've tried now to configure datatable as you told without this variable and still it didn't help :( This filter and two other buttons I've put on upper paginator's place works fine and it doesn't matter, I've tried the default configuration and the problem remains the same :( Thnx for your advices.
  • basejumperbasejumper Posts: 6Questions: 0Answers: 0
    I think it will be easier for all of us if I modify a bit my first comment with code to show the most default configuration with this problem, cause now we are seeking for a problem in my modifications :)
  • GregPGregP Posts: 487Questions: 8Answers: 0
    I'm at a loss. That looks like a pretty solid default configuration.

    If you use Firebug or Developer Tools to monitor network activity, is there only one request for the data?
  • basejumperbasejumper Posts: 6Questions: 0Answers: 0
    edited September 2011
    There are two requests: one standard request to Ajax source, something like http://localhost/newsletters/getdata.php?_=1316161798370 (Firebug Console tab, as a Response we get here our db data) ; the second one can be seen in Net tab, it looks like GET viewer.php (my file with html + datatables configuration, from php there is only extension :) there's a cookie being set etc., as a Response comes whole viewer.php document source ). I don't know, maybe it's a normal situation, cause the first table empty data loading could be seen only in very short period of time, maybe you and other doesn't turn on this attention :D Have you tried to put something like alert(oSettings.aiDisplay.length); somewhere in datatables configuration, for example in "fnDrawCallback": function ( oSettings ) {} ? In my case this alert is called two times, first time it shows me "0", for the second time situation had been normalized and it shows me "51" - correct record count of my table :) Why does it happen two times, I don't know :)
  • GregPGregP Posts: 487Questions: 8Answers: 0
    I'm still at a loss, but I can say that in 'default' configuration, the request should not happen twice.
  • allanallan Posts: 56,480Questions: 1Answers: 8,962 Site admin
    Oddly enough, this hasn't really come up before, but now two threads in the same day :-). Basically the draw happens the first time when the Ajax request goes out initially so DataTables can show the 'Loading...' message (which you can set with - you aren't seeing this due to the backwards compatibility that DataTables has built in - just add in the sLoadingRecords parameter and it should work okay).

    Then a second draw is done the data is loaded - hence two calls to fnDrawCallback.

    If you want to make the call only once - when the table is fully done, then fnInitComplete is the one for you. Alternatively there is an internal market which can be used to check if you want to, but it is internal and thus subject to change (although not going to in 1.8.x...!).

  • basejumperbasejumper Posts: 6Questions: 0Answers: 0
    Thank you allan, GregP for your advices and explanations! Still I haven't succeeded to set sLoadingRecords parameter (I've set it, but still it doesn't shows in the first table draw). During the first table draw programm is showing sEmptyTable parameter if it's defined, if it's not defined - datatables shows me sZeroRecords parameter :D If we have situation with default configuration when oLanguage isn't set or in oLanguage both sEmptyTable and sZeroRecords aren't defined - I can see default (No data available in table) sEmptyTable message.
  • jamovjamov Posts: 5Questions: 0Answers: 0
    edited May 2014

    Old post I know, but ran into this myself with an ajax source. Building on some of the comments above, I used the finInitComplete call to set the the fnDrawCallback that way I know the datatable is initialized

        "fnInitComplete": function(oSettings, json) {                             
             oSettings.fnDrawCallback = alert('redraw');

    Seems I got over zealous with the above, while the alert was executed on fnInitComplete, I later realized that subsequent redraws did not make the call and unfortunately was not able to find a syntax that would allow me to set the drawback function after initialization.

  • allanallan Posts: 56,480Questions: 1Answers: 8,962 Site admin

    That might have worked in very old versions of DataTables, but it certainly won't in newer versions. The settings object is considered to be private and show never be written to unless you are very familiar with how DataTables works internally.

    In this case I would suggest using the public API and add a draw event handler:

    initComplete: function () {
      this.api().on( 'draw', function () {
        alert( 'draw' );
      } );


This discussion has been closed.