FooterCallback is doing 3 calls.

FooterCallback is doing 3 calls.

classic12classic12 Posts: 228Questions: 60Answers: 4
edited December 2017 in DataTables

Hi guys,

all the best to you and yours.

I am using 2 datatables one is connected to my Invoice table the other to my InvoiceDetails table.

I have a dependency that works when the invoiceDetails quantity or sell fields change. This updates the lineTotalNett & lineTotal cells in the row.

       editorInvoiceDetails.dependent( ['inv_list.quantity','inv_list.sellPrice'], function ( val, data ) {
       console.log(' editor on dependent ');
       //event: 'keyup change'
       // need to update all the row total etc and the invoice details
       var quant = Number(editorInvoiceDetails.field( 'inv_list.quantity' ).val());
       var sell = Number(editorInvoiceDetails.field( 'inv_list.sellPrice' ).val());
       var total = quant * sell ;
       var vatRate = Number(editorInvoiceDetails.field( 'inv_list.vatRate' ).val());
       var lineTotal = total* (vatRate/100) ;
       lineTotal = lineTotal + total;
       //console.log('total is ' + total);
       editorInvoiceDetails.set( 'inv_list.lineTotalNett', (total));
       editorInvoiceDetails.set( 'inv_list.lineTotal', (lineTotal));

} , {event: 'keydown'});   

So I am using the footerCallback to calculate the sum and populating the Invoice tables as follows

  $("#dtInvoiceDetails").DataTable().destroy(); 
        $('#dtInvoiceDetails').empty();
        tableInvoiceDetails = $('#dtInvoiceDetails').DataTable( {
         "footerCallback": function ( row, data, start, end, display ) {
            console.log('Invoice details call back called 3 times');
            var api = this.api(), data;
             
             var intVal = function ( i ) {
                return typeof i === 'string' ?
                    i.replace(/[\$,]/g, '')*1 :
                    typeof i === 'number' ?
                        i : 0;
            };
                  var totalNett = api
                .column( 8 )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );

                var total = api
                .column( 9 )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );
 
        totalNett = totalNett.toFixed(2);
        total = total.toFixed(2);
        totalNettVat = total - totalNett;
        totalNettVat = totalNettVat.toFixed(2);
            // Update footer
            console.log(' Total = ' + total);

       tableInvoices.cell( currentSelectedInvoiceIndex, 5 ).data( totalNett ).draw();
       tableInvoices.cell( currentSelectedInvoiceIndex, 6 ).data( totalNettVat ).draw();
       tableInvoices.cell( currentSelectedInvoiceIndex, 7 ).data( total ).draw();
       editorInvoices.edit( currentSelectedInvoiceIndex, false ).submit();
       //editorInvoiceDetails.edit();
       //editorInvoices.create( false ).submit();     

On the select event of the invoice table I have the following which calls the getInvoiceDetails and populates the invoiceDetails table.

$('#dtInvoices').on( 'select.dt', function ( e, dt, type, indexes ) {
          //console.log(' indexes = ' + indexes);
          //alert( 'Row index on select : '+tableInvoices.row( this ).index() );
          currentSelectedInvoiceIndex = indexes ;
          console.log(' currentSelectedInvoiceIndex = ' + currentSelectedInvoiceIndex);
          selectedInvoiceID = tableInvoices.cell('.selected', 0).data();  
     //   if (currentInvoiceID !== selectedInvoiceID )
     //       {
                //selectedInvoiceIndex = tableInvoices.row( this ).index() ;
                currentInvoiceID = selectedInvoiceID;
                selectedOrderNo  = tableInvoices.cell('.selected', 8).data();  
                selectedInvNettTotal  = tableInvoices.cell('.selected', 5).data();  
                selectedInvVatTotal  = tableInvoices.cell('.selected', 6).data();  
                selectedInvTotal  = tableInvoices.cell('.selected', 7).data();  
                selectedPayType  = tableInvoices.cell('.selected', 2).data();
                selectedPayDate  = tableInvoices.cell('.selected', 4).data();  
                selectedInvNotes  = tableInvoices.cell('.selected', 9).data(); 
                selectedDate  = tableInvoices.cell('.selected', 3).data(); 
                selectedDelType  = tableInvoices.cell('.selected', 1).data(); 
                
                
                getInvoiceDetails();
      //      }
      } );

When I change the value of the quantity or sell the console outputs 'console.log('Invoice details call back called 3 times');' from the footerCallback. Sometimes the amounts are not calculated correctly. ( ie I get 0 in the invoice table.)

So I presume the above is causing a loop of some sort.

I need this to happen.

When clicking on the invoice table get the selected invID and call getInvoiceDetails to populate the invoiceDetails table with the relevant data.

Calculate the sum of the columns and update the invoice table.

When the quantity or sell fields are changed do the same.

Is there another event I can use to get the sums ?????

Cheers

Steve Warby

Replies

  • kthorngrenkthorngren Posts: 20,292Questions: 26Answers: 4,768

    In your footerCallback you are calling draw() 3 times. Since the footerCallback is designed to update the footer and not rows within the table, the use draw() within the function is not expected nor desired. Haven't tried it but I suspect this is why you are seeing the footCallback executed multiple times for one update. I can see that this might cause your data calculations to be incorrect.

    I'm not sure I follow the rest of your code but maybe you can put your footerCallback code at the end of the first code snippet you posted. Instead of relying on a callback just process the totals in the same code that is updating the table.

    Also, you should only use draw() on your last update instead of each update. Otherwise you will cause extra, undesired, table processing to take place.

    Kevin

This discussion has been closed.