1
votes

Given this footer_callback datatables example here is my FIDDLE.

This basically sums the total per column for 1 column. Can anyone advise how I can do this for more than 1 column?

I thought I might need to add more th tags for the columns I want to sum:

    <tfoot>
        <tr>
            <th colspan="4" style="text-align:right">Total:</th>
            <th></th>
        </tr>
    </tfoot>

And add another callback function per each column, but so far I have had no joy. Can anyone advise?

        "footerCallback": function ( row, data, start, end, display ) {
        var api = this.api(), data;

        // Remove the formatting to get integer data for summation
        var intVal = function ( i ) {
            return typeof i === 'string' ?
                i.replace(/[\$,]/g, '')*1 :
                typeof i === 'number' ?
                    i : 0;
        };

        // Total over all pages
        total = api
            .column( 4 )
            .data()
            .reduce( function (a, b) {
                return intVal(a) + intVal(b);
            }, 0 );

        // Total over this page
        pageTotal = api
            .column( 4, { page: 'current'} )
            .data()
            .reduce( function (a, b) {
                return intVal(a) + intVal(b);
            }, 0 );

        // Update footer
        $( api.column( 4 ).footer() ).html(
            '$'+pageTotal +' ( $'+ total +' total)'
        );
    }

NOTE: I might need another column in the table/dataset with numbers that I can sum on.
Changed the table so there is 2 columns that can be summed FIDDLE. In this fiddle it is working in col 5 but how do I get it to work in col 3?

2
repeat // Total over all pages , // Total over this page , // Update footer steps for index 3 also.Santhosh Nayak
@SanthoshNayak I have tried that but could you provide an example,tks?HattrickNZ

2 Answers

3
votes

Check out the fiddle here. I'm using the sum plugin. With this approach, you can just add a column index to an array to total it.

I also added the 'applied' filter so the totals dynamically update when filtering.

$(document).ready(function() {

        // SUM PLUGIN
        jQuery.fn.dataTable.Api.register( 'sum()', function ( ) {
            return this.flatten().reduce( function ( a, b ) {
                if ( typeof a === 'string' ) {
                    a = a.replace(/[^\d.-]/g, '') * 1;
                }
                if ( typeof b === 'string' ) {
                    b = b.replace(/[^\d.-]/g, '') * 1;
                }

                return a + b;
            }, 0 );
        } );

        $('#example').DataTable({
            "footerCallback": function () {
                var api = this.api(),
                    columns = [3, 5]; // Add columns here

                for (var i = 0; i < columns.length; i++) {
                    $('tfoot th').eq(columns[i]).html('Total: ' + api.column(columns[i], {filter: 'applied'}).data().sum() + '<br>');
                    $('tfoot th').eq(columns[i]).append('Page: ' + api.column(columns[i], { filter: 'applied', page: 'current' }).data().sum());
                }
            }
        });
    });
0
votes

Just copy and past "footerCallback" and in cols variable give your column position. it will do rest

$(document).ready(function() {
    $('#example').DataTable( {

        "footerCallback": function(row, data, start, end, display) {
            var api = this.api(),
                data;

            // Remove the formatting to get integer data for summation
            var intVal = function(i) {
                return typeof i === 'string' ?
                    i.replace(/[\$a-zA-Z, ]/g, '') * 1 :
                    typeof i === 'number' ?
                    i : 0;
            };

            var cols = [4, 5]; // your columns position will come in this array

            for (let index = 0; index < cols.length; index++) {
                var col_data = cols[index];
                // Total over all pages
                total = api
                    .column(col_data)
                    .data()
                    .reduce(function(a, b) {
                        return intVal(a) + intVal(b);
                    }, 0);

                // Total over this page
                pageTotal = api
                    .column(col_data, {
                        page: 'current'
                    })
                    .data()
                    .reduce(function(a, b) {
                        return intVal(a) + intVal(b);
                    }, 0);

                // Update footer
                $(api.column(col_data).footer()).html(
                    'Total: ' + pageTotal + ' ( GrandTotal: ' + total + ' )'
                );
            }

        },

    } );
} );