fnInitComplete won't run for all datatables

fnInitComplete won't run for all datatables

dudaneskdudanesk Posts: 21Questions: 5Answers: 0

Hi there,

I have 4 datatables on a webpage, all fed from database through Ajax and all processing on client-side. On each of them I want to run a code when the initialization is complete. I'm using fnInitComplete for that. But not all tables will run this code and I can't figure out why. Do you guys see anything wrong with my code?

HTML:

                <td class="blackFilter"><br>
                    <table id="filterCountry" class="display" width="175px">
                        <thead>
                            <tr>
                                <th width="25px"></th>
                                <th width="175px">Country</th>
                            </tr>
                        </thead>
                    </TABLE>
                </td>
                <td class="blackFilter"><br>
                    <table id="filterState" class="display">
                        <thead>
                            <tr>
                                <th width="25px"></th>
                                <th width="175px">State</th>
                            </tr>
                        </thead>
                    </TABLE>
                </td>
                <td class="blackFilter"><br>
                    <table id="filterGallery" class="display">
                        <thead>
                            <tr>
                                <th width="25px"></th>
                                <th width="175px">Gallery</th>
                            </tr>
                        </thead>
                    </TABLE>

JAVASCRIPT:

    $(document).ready(function() {
        
        //number of "buttons" for pagination
        $.fn.DataTable.ext.pager.numbers_length = 15;

        var iniContinent="processing";
        var iniCountry="processing";
        var iniState="processing";

            var continentTable = $('#filterContinent').DataTable( {
            "info": false,
            "bLengthChange": false,
            "pagingType": "numbers",
            select: {
                style: 'multi'
            },
            "ajax": 'c_continent.php',
            'columnDefs': [
                {
                    'targets': 0,
                    'checkboxes': {'selectRow': true},
                    'createdCell':  function (td, cellData, rowData, row, col){
                        this.api().cell(td).checkboxes.select();
                    },
                },
                {'targets': 1, 'orderable': false},
            ],
            "fnInitComplete": function(oSettings, json) {
                alert("continentTable initialized");
                iniContinent="done";
                countryTable.ajax.reload();
            }
        } );
        
        var countryTable = $('#filterCountry').DataTable( {
            "info": false,
            "bLengthChange": false,
            "pagingType": "numbers",
            'order': [[1, 'asc']],
            select: {
                style: 'multi'
            },
            "ajax": {
                "url": "c_country.php",
                "type": "POST",
                "data": function ( d ) {
                    var retrieveIDs="";
                    var myIDs = continentTable.rows('.selected').data().toArray();
                    for ( var i=0 ; i<myIDs.length ; i++ ){
                        retrieveIDs += myIDs[i][0]+",";
                    }
                    d.continentIDs = retrieveIDs;
                }
            },
            'columnDefs': [
                {
                    'targets': 0,
                    'checkboxes': {'selectRow': true},
                    'createdCell':  function (td, cellData, rowData, row, col){
                        this.api().cell(td).checkboxes.select();
                    },
                },
                {'targets': 1, 'orderable': false},
            ],
            "fnInitComplete": function(oSettings, json) {
                alert("countryTable initialized");
                iniCountry="done";
                stateTable.ajax.reload();
            }
        } );
        
        var stateTable = $('#filterState').DataTable( {
            "info": false,
            "bLengthChange": false,
            "pagingType": "numbers",
            'order': [[1, 'asc']],
            'columnDefs': [
                {
                    'targets': 0,
                    'checkboxes': {'selectRow': true},
                    'createdCell':  function (td, cellData, rowData, row, col){
                        this.api().cell(td).checkboxes.select();
                    },
                },
                {'targets': 1, 'orderable': false},
            ],
            select: {
                style: 'multi'
            },
            "ajax": {
                "url": "c_state.php",
                "type": "POST",
                "data": function ( d ) {
                    var retrieveIDs="";
                    var myIDs = countryTable.rows('.selected').data().toArray();
                    for ( var i=0 ; i<myIDs.length ; i++ ){
                        retrieveIDs += myIDs[i][0]+",";
                    }
                    d.countryIDs = retrieveIDs;
                }
            },
            "fnInitComplete": function(oSettings, json) {
                alert("stateTable initialized");
                iniState="done";
                galleryTable.ajax.reload();
            }
        } );
        
        var galleryTable = $('#filterGallery').DataTable( {
            "info": false,
            "bLengthChange": false,
            "pagingType": "numbers",
            'order': [[1, 'asc']],
            'columnDefs': [
                {
                    'targets': 0,
                    'checkboxes': {'selectRow': true},
                    'createdCell':  function (td, cellData, rowData, row, col){
                        this.api().cell(td).checkboxes.select();
                    },
                },
                {'targets': 1, 'orderable': false},
            ],
            select: {
                style: 'multi'
            },
            "ajax": {
                "url": "c_gallery.php",
                "type": "POST",
                "data": function ( d ) {
                    var retrieveIDs="";
                    var myIDs = stateTable.rows('.selected').data().toArray();
                    for ( var i=0 ; i<myIDs.length ; i++ ){
                        retrieveIDs += myIDs[i][0]+",";
                    }
                    d.stateIDs = retrieveIDs;
                }
            },
            "fnInitComplete": function(oSettings, json) {
                alert("galleryTable initialized");
                iniGallery="done";
            }
        } );
        
        continentTable.on( 'select', function () {
            if(iniContinent=="done"){
                countryTable.ajax.reload();
            }
        } );
        continentTable.on( 'deselect', function () {
            countryTable.ajax.reload();
        } );
        
        countryTable.on( 'select', function () {
            if(iniCountry=="done"){
                stateTable.ajax.reload();
            }
        } );
        countryTable.on( 'deselect', function () {
            stateTable.ajax.reload();
        } );
        
        stateTable.on( 'select', function () {
            if(iniState=="done"){
                galleryTable.ajax.reload();
            }
        } );
        stateTable.on( 'deselect', function () {
            galleryTable.ajax.reload();
        } );
        
    } );

Live example:
http://one-world.comeze.com/c_test.php

I have an alert() message on fnInitComplete for each table to et me know if the code is being run. It seems it always run for my first table, and more often than not on my third table. But never for the four of them. Any clue why?

Also, can I somehow force datatables to be initialized in a specific order? I need continentTable to be initialized first, then countryTable second, stateTable third and finally galleryTable last

Thanks guys

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,197Questions: 26Answers: 4,926
    Answer ✓

    Looks like you are using DT 1.10.16 but using legacy versions of the DT options. You can continue using the legacy commands but you may want to consider changing to the current scheme. This is the conversion chart. This isn't causing your issue though.

    The load order of the Datatables is the order you have them in the script. Although some may take longer to complete than others. AJAX is asynchronous in operation to keep the web page from freezing while waiting to the data. While your first table is being fetched Javascript is starting the next and so on.

    In your continentTable table you have countryTable.ajax.reload(); in the fnInitComplete function. Same with the other tables attempting to reload the next in your desired order. I think this is causing race conditions when loading your tables causing them to not load consistently. You can watch the network tab of the browser's dev tools to see what's happening. You can see inconsistent loading of the tables.

    I think you should remove the reload commands and replace them with functions. Put each DT init into its own function then in the initComplete function of continentTable call the function to load the next table. Then in that table's initCompete call the function for the next table. And so on.

    There may be better options that others may post to help you load the tables in the desired order.

    Kevin

  • dudaneskdudanesk Posts: 21Questions: 5Answers: 0

    Thanks Kevin.
    Firstly, I upgraded my fnInitComplete for initComplete.

    Then I tried to use functions called in initComplete as you suggested, but I wasn't successful, I had the same issue. I do agree with you though, I think all my ajax.reload() in initComplete for all my tables are probably confusing for the system. So I tried to think of another way to do what what I'm trying to do, but I can't come up with anything.

    So let me try to explain what I'm doing with my webpage.
    I have 4 datatables: continentTable, countryTable, stateTable and galleryTable. When the user selects one or more continent, I update the countries so they match the selected continent(s). Same thing when the user selects one or more countries, I update the states. And so on. I launch the update of the datatable with the event table.on( 'select', function () {}. All this works just fine. The trick is I want all continents to be selected on initialization, which means all countries will be displayed and selected too on initialization, same with states and galleries. But doing this means that, during initialization of continentTable, my event table.on( 'select', function () {} will be launched 6 times (I have 6 rows/continents), which is to say countryTable is updates 6 times when, really, I whish to update it only once when continentTable is entirely loaded. How not to trigger table.on( 'select', function () {} for every row created and selected but only once when initialization is complete?
    It's not too bad for continentTable because there are only 6 rows in there, but by the time I get to stateTable and its 64 rows, I'm updating galleryTable 64 times!!! Not exactly an efficient piece of code.

    Am I making any sense here? Is there a way to trigger table.on( 'select', function () {} only once for each table upon completion of initialization and then every time the user select/deselect a row?

This discussion has been closed.