footerCallback adding footer row for every event

footerCallback adding footer row for every event

missingsemicolonmissingsemicolon Posts: 3Questions: 1Answers: 0

Hi,
I have this code where I'm adding footer row dynamically & adding column sum values.
This works fine except for inserting a footer row for every event. I understand the callback happens for every event but how do I stop inserting footer row for every event? I just need the row added once and stay as-is. It doesn't need to recalculate total values based on filter selection or search values.

I replaced "footerCallback" with "initComplete" to stop duplicating footer rows.

$(function () {
$.ajax({
type: "POST",
url: "Default.aspx/GetCustomerData",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
});
function OnSuccess(response) {
console.log(response.d);
$("[id*=gvCustomer]").DataTable(
{
bLengthChange: true,
lengthMenu: [[5, 10, -1], [5, 10, "All"]],
iDisplayLength: -1,
bFilter: true,
bSort: true,
ordering: true,
order: [[0, "asc"]],
bPaginate: true,
autoWidth: false,
data: response.d,
columns: [{ 'data': 'CustomerName', "width": "20%"},
{
'data': 'Revenue', "width": "20%",
'render': function (data) {
return '£' + data;
}},
{
'data': 'Margin', "width": "20%",
'render': function (data) {
return '£' + data;
}
}],

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

                    var footer = $(this).append('<tfoot><tr></tr></tfoot>');

                    $(footer).append('<th class="text-center">Total:</th>');

                    this.api().columns(1).every(function () {
                        var column = this;
                        revTotal = column
                            .data()
                            .reduce(function (a, b) {
                                var x = parseFloat(a) || 0;
                                var y = parseFloat(b) || 0;
                                return x + y;
                            }, 0);

                        $(footer).append('<th class="text-left">' + revTotal + '</th>');
                    });

                    this.api().columns(2).every(function () {
                        var column = this;
                        marTotal = column
                            .data()
                            .reduce(function (a, b) {
                                var x = parseFloat(a) || 0;
                                var y = parseFloat(b) || 0;
                                return x + y;
                            }, 0);

                        $(footer).append('<th class="text-left">' + marTotal + '</th>');
                    });
                }

            });
    };

Thanks in advance.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,352Questions: 26Answers: 4,955
    edited November 2021

    For lines 6-8 - Either create the footer before initializing Datatables or check in the footerCallback it exists and create it if it doesn't.

    In line 33 update the HTML, like this example, instead of appending to the footer.

    Kevin

  • missingsemicolonmissingsemicolon Posts: 3Questions: 1Answers: 0
    edited November 2021

    Thanks for responding Kevin.

    Sorry, where exactly do I need to create the footer in this code?

    Thanks

  • kthorngrenkthorngren Posts: 21,352Questions: 26Answers: 4,955
    edited November 2021 Answer ✓

    Either create the footer in HTML with your table, like the example I linked to (click the html tab) or in Javascript before you initialize Datatables. Maybe you already have a footer that just needs updating. If you want help please provide a test case showing what you have so we can provide a more specific answer.
    https://datatables.net/manual/tech-notes/10

    Kevin

  • missingsemicolonmissingsemicolon Posts: 3Questions: 1Answers: 0

    Thanks Kevin.

    The datatable does not have tfoot element. I was adding it dynamically.

    I updated the code to add the footer using createTFoot() function before initializing the datatable and updating totals using .html() as you suggested.

    Thank you for your help.

    Updated code:

        $(function () {
            $.ajax({
                type: "POST",
                url: "Default.aspx/GetCustomerData",
                data: '{}',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: OnSuccess,
                failure: function (response) {
                    alert(response.d);
                },
                error: function (response) {
                    alert(response.d);
                }
            });
        });
        function OnSuccess(response) {
            console.log(response.d);
            createFooter();
    
            $("[id*=gvCustomer]").DataTable(
                {
                    bLengthChange: true,
                    lengthMenu: [[5, 10, -1], [5, 10, "All"]],
                    iDisplayLength: -1,
                    bFilter: true,
                    bSort: true,
                    ordering: true,
                    order: [[0, "asc"]],
                    bPaginate: true,
                    autoWidth: false,
                    data: response.d,
                    columns: [{ 'data': 'CustomerName', "width": "20%"},
                        {
                            'data': 'Revenue', "width": "20%",
                            'render': function (data) {
                                return '£' + data;
                            }},
                        {
                            'data': 'Margin', "width": "20%",
                            'render': function (data) {
                                return '£' + data;
                            }
                        }],
    
                    'footerCallback': function (row, data, start, end, display) {
                        var api = this.api();
                        var revTotal;
                        var marTotal;
    
                        //$(footer).append('<th class="text-center">Total:</th>');
    
                        this.api().columns(1).every(function () {
                            var column = this;
                            revTotal = column
                                .data()
                                .reduce(function (a, b) {
                                    var x = parseFloat(a) || 0;
                                    var y = parseFloat(b) || 0;
                                    return x + y;
                                }, 0);
    
                            //$(footer).append('<th class="text-left">' + revTotal + '</th>');
                            $(api.column(1).footer()).html(revTotal);
                        });
    
                        this.api().columns(2).every(function () {
                            var column = this;
                            marTotal = column
                                .data()
                                .reduce(function (a, b) {
                                    var x = parseFloat(a) || 0;
                                    var y = parseFloat(b) || 0;
                                    return x + y;
                                }, 0);
    
                            $(api.column(2).footer()).html(marTotal);
                        });
                    }
    
                });
        };
    
        function createFooter() {
            console.log("test");
            var tables = document.getElementById("gvCustomer");
    
            var footer = tables.createTFoot();
    
            //$(footer).append('<th class="text-center">Total:</th>');
            var row = footer.insertRow(0);
            var cell = row.insertCell(0);
            cell.innerHTML = "<b>Total:</b>";
            var cell1 = row.insertCell(1);
            var cell2 = row.insertCell(2);
        };
    

    Note: gvCustomer is a gridview:

            <asp:GridView ID="gvCustomer" runat="server" CssClass="display compact" AutoGenerateColumns="false">
                <Columns>
                    <asp:BoundField DataField="CustomerName" HeaderText="SalesRep" />
                    <asp:BoundField DataField="Revenue" HeaderText="Revenue" />
                    <asp:BoundField DataField="Margin" HeaderText="Margin" />
                </Columns>
            </asp:GridView>
    
Sign In or Register to comment.