initComplete is throwing error of table not defined

initComplete is throwing error of table not defined

antidotantidot Posts: 8Questions: 2Answers: 0

Hi. After a few weeks i am starting getting familar with datatables. Great work btw.

Here is my problem:

I am loading data via jquery ajax call and store it in an array.
Using the jquery .done() method i then do all the init stuff...

if i use initComplete without the timeout function i always get table is undefined

Maybe i missunderstand the initComplete option ?

`$(document).ready(function() {

$.ajax({url: "Data.do", success: function(result){
    console.log('success',result);
    temporaryTableContent=JSON.parse(result);
    //console.log(temporaryTableContent);
  },
  error: function(result){
    console.log('error: ',result);
  }
}).done(function(){

  temporaryTableContent.forEach(function (arrayItem) {
                          if (arrayItem.usergroup == null){
                            arrayItem.usergroup = replaceNull;
                            }
                        });

    // Setup - Add text input or select to each header cell with class sort-text or sort-select
    $('#mitarbeiter thead tr').clone(true).appendTo( '#mitarbeiter thead' ); // clone
        // Erzeugen eines Text-Input oder Select Elements
        $('#mitarbeiter thead tr:eq(1) th').each( function (i) {
          console.log('AKTIV')
            var title = $(this).text();
            var sortClass = $(this).attr('class');
            //console.log("sortClass",sortClass);
            if (sortClass == "sort-text"){
            $(this).html( '<input type="text" class="form-control input-sm" placeholder="Search '+title+'" />' );

              $( 'input', this ).on( 'keyup change', function () {
              //console.log(table.column(i));
                  if ( table.column(i).search() !== this.value ) {
                      table
                          .column(i)
                          .search( this.value )
                          .draw();
                  }
              } );
            }
            else if(sortClass == "sort-select"){
              var column = $(this);
              var select = '<select class="btn-default btn-sm btn-select"><option value="" selected>Select</option><option value="'+replaceNull+'">'+replaceNull+'</select>';
              $(this).html(select);

                $( 'select', this ).on( 'change', function () {
                  var val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );
                            //console.log('val',val);
                              table
                              .column(i)
                              .search( val ? '^'+val+'$' : '', true, false )
                              .draw();
                        } );
            }
            else{$(this).html('');}
        } );

  var table = $('#mitarbeiter').DataTable({
  data: temporaryTableContent,
  "initComplete": function(){
                        setTimeout(function(){
                        var gaga = table.columns('.sort-select');
                        var colINDEX=gaga.indexes();
                        for (var i=0;i < colINDEX.length; i++){
                          //console.log('this',table.column(colINDEX[i]).row(1).context[0].aoHeader[1][colINDEX[i]]);

                          // Das aktuelle SELECT Element
                          var x = table.column(colINDEX[i]).row(1).context[0].aoHeader[1][colINDEX[i]].cell.children[0];  
                        // Hole Indizes aus colINDEX
                            table.columns(colINDEX[i]).data().eq(0).sort().unique().each( function ( d, j ) {

                            if(d != replaceNull){
                            var option = document.createElement("option");
                            option.value = d;
                            option.text = d;
                            x.add(option);
                            }
                            });
                          }
                        },100);
                    },
  "columnDefs": [ 
    {
      "targets": 0,
      "data": 'name',
      },
    {
      "targets": 1,
      "data": 'usergroup'
      },      
    {
      "targets": 2,
      "data": 'email'
    },
    {
      "targets": 3,
      "data": 'phone'
    },
    {
      "targets": 4,
      "data": 'mobile'
    },{
    "targets": 5,
    "data": 'id',
    "sortable": false,
    "render": function ( data, type, full, meta ) {
      // return '<button class="glyphicon glyphicon-trash" id="'+data+'"></button>';
      return '<a href="#" class="glyphicon glyphicon-pencil" onclick="openWindowEdit('+data+')" style="padding-right:1em"></a><a href="/heidler/webapp/admin/geraet/geraeteData.do?action=DELETE&amp;id='+data+'" class="glyphicon glyphicon-trash" onclick="return deleteWarningDE()"></a>'
    }
    } 
  ],
  "processing": true,
  "orderCellsTop": true,
  "fixedHeader": true,
  "order": [[0, 'asc']],
  "responsive": false,
  "paging": true,
  "pagingType": "full_numbers",
    "lengthChange": true,
    "searching": true,
    "ordering": true,
    "info": true,
    "lengthMenu": [[10, 25, 50, 500], [10, 25, 50, 500]],
    "drawCallback": function () {
        $('.dataTables_paginate > .pagination').addClass('pagination-sm'); 
    }
});
})

});`

Answers

  • kthorngrenkthorngren Posts: 21,160Questions: 26Answers: 4,921

    The initComplete function and a few other callbacks get the Datatables API instance for the table. Here is an example of how to use it:
    http://live.datatables.net/nedizoro/1/edit

    As you figured out the variable you assigned to the Datatable isn't ready for use until after Datatables completes initialization.

    Kevin

  • antidotantidot Posts: 8Questions: 2Answers: 0

    So this means i have to change the code using the api instance or write a listener which is checking if table is available or not?

    Marc

  • kthorngrenkthorngren Posts: 21,160Questions: 26Answers: 4,921
    edited September 2019

    So this means i have to change the code using the api instance or write a listener which is checking if table is available or not?

    The initComplete function is executed once the Datatable has been initialized. The problem is the initialization process (function) has not returned yet so the variable (table) doesn't contain the API object yet. Essentially var table = $('#mitarbeiter').DataTable(...) is calling a function and initCompete is part of that function. So the table variable doesn't have the Datatbles API object until the initComplete is finished and the DataTable() function has returned.

    Not sure if I'm answering your question.

    Kevin

  • antidotantidot Posts: 8Questions: 2Answers: 0

    Hi Kevin. Thanks.
    This was more clear :-)
    Just the Description of initComplet

    Description

    It can often be useful to know when your table has fully been initialised, data loaded >and drawn,...

    made me believe thats running after fished completely.

    So my final question:

    I have to take care about that state myself? (not a big thing..)

  • kthorngrenkthorngren Posts: 21,160Questions: 26Answers: 4,921

    I have to take care about that state myself?

    Please clarify your question. What "state" are you referring to?

    Kevin

  • antidotantidot Posts: 8Questions: 2Answers: 0

    The "state" where the table is fully done, so i can fill the select fields with the values needed :-)

  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    Hi @antidot ,

    Yep, that's initComplete you need - that runs after the Ajax call has replied and the data loaded.

    Cheers,

    Colin

  • antidotantidot Posts: 8Questions: 2Answers: 0

    Hi @colin ,

    nope :-)
    that was what i expected, but it runs before it's fully loaded...

    so i needed to set a timeout in this example!
    I just gonna write some "watchscript" and then execute it :-)
    No worries. But still very irritating

  • kthorngrenkthorngren Posts: 21,160Questions: 26Answers: 4,921
    edited September 2019

    Are you saying the problem is that the table variable is undefined in initComplete? If so that is to be expected. I showed the proper way to access the Datatable API in initComplete by using var api = this.api();.

    It looks list you are doing something similar as this footerCallback example. Note the use of var api = this.api() to access the API.

    If this isn't the problem then please explain what you need the "watchscript" for so we can understand the problem better.

    Kevin

  • antidotantidot Posts: 8Questions: 2Answers: 0

    @kthorngren

    I think the api solution might work. Sorry couldn't try it out yet...
    And sorry for my obviously bad description of the problem, but english isn't my mother tongue :-)

This discussion has been closed.