Cannot read property 'node' of undefined table.on( 'select deselect', function ()

Cannot read property 'node' of undefined table.on( 'select deselect', function ()

bbrindzabbrindza Posts: 136Questions: 29Answers: 1

I am using the table.on( 'select deselect', function () to set a button to enabled .

It work the first time the AJAX data loads, however when I reload the page with new AJAX data, I receive this error "Cannot read property 'node' of undefined"

What am I missing?

  table.on( 'select deselect', function () {
      var selectedRows = table.rows( { selected: true } ).count();
      table.button( 0 ).enable( selectedRows > 0 );
  });
  

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 10,716Questions: 25Answers: 2,449

    There is not enough information to help. Can you post a link to your page or a test case so we can understand the code flow and help debug?
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • bbrindzabbrindza Posts: 136Questions: 29Answers: 1

    Kevin, The application uses PHP to populate the table. Not sure how to do this in live.datatables.net . Would the JS be enough for you to look at the code? If so I can add it with Markdown

  • kthorngrenkthorngren Posts: 10,716Questions: 25Answers: 2,449

    Sure you can post your code. Someone may be able to spot something.

    How are you reloading the page? Is it a full page reload or just reloading the table data. If you are just reloading the table data then you will either need to use something like rows().invalidate() to refresh the Datatables data cache or reinitialize Datatables.

    Kevin

  • bbrindzabbrindza Posts: 136Questions: 29Answers: 1

    Just reloading the table. I have a datePicker when onChange runs the reloadReportTable function on line 149 where I clear and destroy the table before reloading.

    Would I put the rows().invalidate() after that?

    Here is the JS .

    loadTable();
    //***************************************************************** 
    // Load Time Log Table 
    //***************************************************************** 
    function loadTable(){ 
    
      var table = $('#timeLogTable_WeekEnding').DataTable( {
    
        displayLength:50,
        fixedHeader: true,
         dom: 'Bfrtip',
         buttons:[
                  {
                     text: 'Aprrove Hours',
                     init: function(api, node, config) {
                            $(node).removeClass('dt-button buttons-print');
                            $(node).attr( 'id', 'approveHours' );
                      },
                     
                     className: 'btn btn-primary',
                     action: function ( e, dt, node, config ) {
                            setApprovedHours()
                      },
                     enabled: false
                   },
                  {
                    extend: 'print', 
                    init: function(api, node, config) {
                        $(node).removeClass('dt-button buttons-print')
                     },
                    className: 'btn btn-primary',
                    exportOptions: {
                        columns: [  4, 5, 6, 7, 8, 9, 10, 12, 15, 17]
                    },
                    title: 'Week Ending Report '+  $('#weekEndingDate').val() + " for Manager: " + managerName,
                    
                    customizeData: includeSubtotals,
    
                    customize: function(win) {
                    $(win.document.body).find('h1').css('font-size', '15pt');   
                    $(win.document.body)
                                .css( 'font-size', '8pt' );
         
                    $(win.document.body).find( 'table' )
                                .addClass( 'compact' )
                                .css( 'font-size', 'inherit' );
         
                        var last = null;
                        var current = null;
                        var bod = [];
         
                       var css = '@page { size: landscape; font-size: 8px}',
                            head = win.document.head || win.document.getElementsByTagName('head')[0],
                            style = win.document.createElement('style');
         
                        style.type = 'text/css';
                        style.media = 'print';
         
                        if (style.styleSheet)
                        {
                          style.styleSheet.cssText = css;
                        }
                        else
                        {
                          style.appendChild(win.document.createTextNode(css));
                        }
         
                        head.appendChild(style);
                 }
                  },
                ],
        language: {  sSearch: 'Table Search: '},
        processing: true,
        serverSide: true,
        ajax: {
                url: "ssp_TimeLogTable_WeekEnding.php",
                dataType: 'json',
                data: { weekEndingDate: $('#weekEndingDate').val(),
                        managerNumber: managerNumber },
        },
        columns: [
               { orderable: false,  
                 data: null,
                 defaultContent: '',
                },
                  { data: 'rowID', 'visible': false },
                  { data: 'week_ending_date_row_group', 'visible': false}, 
                  { data: 'employee_information_row_group', 'visible': false }, 
                  { data: 'employee_full_name', orderable: false, 'visible': false}, 
                  { data: 'employee_department_code', orderable: false, 'visible': false},
                  {
                   orderable:      false,
                   data:           null,
                   defaultContent: '',
                  },
                  { data: 'time_log_date', orderable: false },
                  { data: 'time_in', orderable: false },
                  { data: 'lunch_out', orderable: false },
                  { data: 'lunch_in', orderable: false },
                  { data: 'time_out', orderable: false },
                  { data: 'hours_worked', orderable: false },
                  { data: 'total_gross_time_format', orderable: false, 'visible': false},
                  { data: 'total_lunch', orderable: false },
                  { data: 'total_hours', orderable: false },
                  { data: 'total_hours_time_format', orderable: false, 'visible': false},
                  { data: 'out_of_office', orderable: false },
                  { data: 'hours_approved', orderable: false, 'visible': false }
                ] , 
           columnDefs: [
                    {
                      targets: 0,
                      render: function(data, type, row, meta){
                          data = '<input type="checkbox" class="select-checkbox">'
                          
                          if(row['hours_approved'] == 'Y'){
                             data = '<span class="checkMark">&#10003</span>';
                          }
                          
                          return data;
                       },
                    createdCell:  function (td, cellData, rowData, row, col){
                        if(rowData['hours_approved'] == 'Y'){
                            this.api().cell(td).checkboxes.disable();
                         }
                       },            
    
                    },
                 ],
        select: {style: 'multi' },              
        order: [ [ 3, 'asc']],
        rowGroup: {
                  dataSrc: [ 'week_ending_date_row_group',  'employee_information_row_group' ],
        },
        createdRow: function( row, data, dataIndex ) {
                  $(row).addClass( 'total-row' );
         },
    
         drawCallback: addSubtotals, 
            
      });//END .dataTable
        
      table.on( 'select deselect', function () {
          var selectedRows = table.rows( { selected: true } ).count();
          table.button( 0 ).enable( selectedRows > 0 );
      });
      
    }
    
    function reloadReportTable(){ 
    
        $("#timeLogTable_WeekEnding").DataTable().clear().destroy();
    
        loadTable()
    }
    
  • kthorngrenkthorngren Posts: 10,716Questions: 25Answers: 2,449
    Answer ✓

    I built a test case for you.
    http://live.datatables.net/turanowo/1/edit

    It uses the server side base code as described in this technote. I copied the portions of your code to replicate the issue. The problem is that each time loadTable() is called a new select deselect event handler is created without removing the old one. After executing reloadReportTable() there are now two events. The first one runs but is looking for the reference to the old Datatable that is destroyed.

    I added the statement $("#example").DataTable().off( 'select deselect'); and now it works as expected. Comment you this line to see your problem reproduced.

    Kevin

  • bbrindzabbrindza Posts: 136Questions: 29Answers: 1

    Kevin thank you so much for the effort. You are a wizard! Kind regards and keep up the good work

Sign In or Register to comment.