footerCallback on a of a child table

footerCallback on a of a child table

jalapejalape Posts: 117Questions: 2Answers: 1

Good afternoon,
I have a child table built from a function:

function createChild ( row ) {
var table = $('<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tfoot>'+
'<tr>'+
'<th colspan="4" style="text-align:right">'+
'Suma:'+
'</th>'+
'</tr>'+
'</tfoot>'+        
'</table>');
 
 row.child( table ).show();
...

The fields are mounted from the columns:

        columns: [
            { title: 'Tipo', data: 'tb_objeto.objeto' },
            { title: 'Item', data: 'tb_item.item' }
    …

To fill the Sum of the <tfoot> I use a "footerCallback": function
The question is: How can I pass the data from the footerCallback to the <tfoot>
Thank you.

Replies

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • jalapejalape Posts: 117Questions: 2Answers: 1
    edited August 2020

    Sorry, I didn't think it was necessary this time. The path is: http://javierlasen.es/easd/login/admin_nota.php.
    The secondary table is displayed by clicking on any record in the "Sec" field of the main table.
    In the secondary table, “Suma” would have to calculate the sum of all the records in the “Media” field.
    To have data in the secondary table, write in the Search of the main table, the value 1348.
    Thank you

  • allanallan Posts: 61,438Questions: 1Answers: 10,049 Site admin

    Hi,

    The best way to write into a footer element is with the column().footer() method as shown in this example.

    Allan

  • jalapejalape Posts: 117Questions: 2Answers: 1

    Thanks Allan for answering,
    I have put it following the example, the problem is that I don't know how to pass the sum data to the footer of the secondary table.
    I have tried it this way:

    function createChild ( row ) {
        // This is the table we'll convert into a DataTable
        var table = $('<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
            '<tfoot>'+
                '<tr>'+
                    '<th colspan="4" style="text-align:right">'+
                        'Suma: '+
     
    "'$'+pageTotal +' ($'+ total +' total)'"+
    
                    '</th>'+
                '</tr>'+
            '</tfoot>'+        
        '</table>');
     
        // Display it the child row
        row.child( table ).show();
     
        // Initialise as a DataTable
        var rowData = row.data();
        var usersEditor = new $.fn.dataTable.Editor( {
            ajax: {
                url: 'php/p_datos/datos_users.php',
                data: function ( d ) {
                    d.variable = rowData.tb_nota.id;
                }
            },
            table: table,
            fields: [ {
                    label: "First name:",
                    name: "users.first_name"
                }, {
                    label: "Last name:",
                    name: "users.last_name"
                }, {
                    label: "Phone #:",
                    name: "users.phone"
                }
            ]
        } );
    
        //Actualizar la tabla principal
        usersEditor.on( 'submitSuccess', function (e, json, data, action) {
            row.ajax.reload(function () {
                $(row.cell( row.id(true), 0 ).node()).click();
            });
        } );
    
    
        var usersTable = table.DataTable( {
            dom: 'Bfrtip',
            pageLength: 5,
            ajax: {
                url: 'php/p_datos/datos_users.php',
                type: 'post',
                data: function ( d ) {
                    d.variable = rowData.tb_nota.id;
                }
            },
            columns: [
                { title: 'Tipo', data: 'tb_objeto.objeto' },
                { title: 'Item', data: 'tb_item.item' },
                {
                    title: '%',
                    data: null,
                    render: function ( data, type, row ) {
                        return data.vista_item.porcentaje + "%";
                    }
                },
                { title: 'Nota', data: 'vista_item.nota_item' },
                {
                    title: 'Media',
                    data: null,
                    render: function ( data, type, row ) {
                        return ((data.vista_item.porcentaje * data.vista_item.nota_item) / 100).toFixed(2);
                    }
                },
            ],
    
    
    
            select: true,
            buttons: [
                { extend: 'create', editor: usersEditor },
                { extend: 'edit',   editor: usersEditor },
                { extend: 'remove', editor: usersEditor }
            ],
            /*
            Para sumar los datos numéricos de una columna (con paginación)
            https://datatables.net/forums/discussion/46296/calculating-cells-values
            */
            "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
                .cells( null, 4 )
                .render('display') 
                .reduce( function (a, b) {
                    return (intVal(a) + intVal(b)).toFixed(2);
                }, 0 );
    
                // Total over this page
                pageTotal = api
                .cells( null, 4, { page: 'current'} )
                .render('display')          
                .reduce( function (a, b) {
                    return (intVal(a) + intVal(b)).toFixed(2);
                }, 0 );
    
                // Update footer
                $( api.column( 4 ).footer() ).html(
                    '$'+pageTotal +' ($'+ total +' total)'
                );
    
            }
        } );
    
    }
    
    
    
    function destroyChild(row) {
        var table = $("table", row.child());
        table.detach();
        table.DataTable().destroy();
     
        // And then hide the row
        row.child.hide();
    }
    
    
    
    function updateChild ( row ) {
        $('table', row.child()).DataTable().ajax.reload();
    }
    
    
    
    $(document).ready(function() {
        var siteEditor = new $.fn.dataTable.Editor( {
            ajax: 'php/p_datos/datos_nota.php',
            table: '#nota_tbl',
            fields: [ {
                label: 'Site name:',
                name: 'name'
            } ]
        } );
    
        var siteTable = $('#nota_tbl').DataTable( {
            dom: 'Bfrtip',
            order: [ 1, 'asc' ],
            ajax: 'php/p_datos/datos_nota.php',
            columns: [
                {
                    className: 'details-control',
                    orderable: false,
                    data: null,
                    defaultContent: '',
                    width: '10%'
                },
                { data: "tb_nota.id" },   
                { data: "tb_estudios.estudios" },
                { data: "tb_especialidad.especialidad" },
                { data: "tb_asignatura.asignatura" },
                { 
                    data: 'vista_item', render: function ( data ) {
                        return data.length;
                    } 
                }
            ],
            select: {
                style:    'os',
                selector: 'td:not(:first-child)'
            },
            buttons: [
                { extend: 'create', editor: siteEditor },
                { extend: 'edit',   editor: siteEditor },
                { extend: 'remove', editor: siteEditor }
            ]
        } );
    
    
    
        $('#nota_tbl tbody').on('click', 'td.details-control', function () {
            var tr = $(this).closest('tr');
            var row = siteTable.row( tr );
         
            if ( row.child.isShown() ) {
                // This row is already open - close it
                destroyChild(row);
                tr.removeClass('shown');
            }
            else {
                // Open this row
                createChild(row, 'child-table'); // class is for background colour
                tr.addClass('shown');
            }
        } );
    
    
    
        siteEditor.on('submitSuccess', function () {
            siteTable.rows().every(function () {
                if (this.child.isShown()) {
                    updateChild(this);
                }
            });
        } );
    
    } );
    
  • kthorngrenkthorngren Posts: 20,140Questions: 26Answers: 4,735

    The problem is you are trying to use the summation variables when crating your tfoot, ie, line 9 in the above code. Structure your footer like the example Allan linked to. Click on the HTML tab and scroll to the bottom to see the footer. Line 120 will take care of populating the footer with the sum value.

    Kevin

  • jalapejalape Posts: 117Questions: 2Answers: 1

    Thanks kthorngren for replying,
    But in my case the html file only has the main table, the secondary table is created with the variable "table" in line 3. From the datatable_nota.js file of the previous comment, and fill the fields with the "columns" of the line 60.
    This is the html of the main file admin_nota.php

    <!-- https://datatables.net/blog/2019-01-11 -->
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <link rel="shortcut icon" type="image/ico" href="http://www.datatables.net/favicon.ico">
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, user-scalable=no">
        <title>Notas</title>
    
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.1/css/buttons.dataTables.min.css">
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.min.css">
        <link rel="stylesheet" type="text/css" href="plugin/editorr/1.9.3/css/editor.dataTables.min.css">
    
        
    
        
        <script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
        <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
        <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.6.1/js/dataTables.buttons.min.js"></script>
        <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.min.js"></script>
        <script type="text/javascript" language="javascript" src="js/dataTables.editor.min.js"></script>
    
        
    <style type="text/css">
        /*td.details-control {
            background: url('resources/details_open.png') no-repeat center center;
            cursor: pointer;
        }*/
    /*  tr.shown td.details-control {
            background: url('resources/details_close.png') no-repeat center center;
        }*/
    </style>
    
    
    </head>
    <body class="dt-example php">
        <div class="container">
            <section>
                <h1>Notas</h1>
                <div class="demo-html"></div>
    
                <table id="nota_tbl" class="display" style="width:100%">
                    <thead>
                        <tr>
                            <th>Sec</th>
                            <th>Nota Id</th>
                            <th>Estudios</th>
                            <th>Especialidad</th>
                            <th>Asignatura</th>
                            <!-- <th>Users</th> -->
                            <th>Items</th>
                        </tr>
                    </thead>
                </table>
            </section>
        </div>
    
        <script type="text/javascript" language="javascript" src="php/js/datatable_nota.js"></script>
    </body>
    </html>
    
  • kthorngrenkthorngren Posts: 20,140Questions: 26Answers: 4,735

    But in my case the html file only has the main table, the secondary table is created with the variable "table" in line 3. From the datatable_nota.js

    Yes, I understand. The -tag tfootis created in that function and is part of the-tag table` assigned to the child table. Did you try my recommendation? You want something like this:

        var table = $('<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
            '<tfoot>'+
                '<tr>'+
                    '<th colspan="4" style="text-align:right">Suma:</th>'+
                    '<th></th>'+
                '</tr>'+
            '</tfoot>'+       
        '</table>');
    

    Kevin

  • jalapejalape Posts: 117Questions: 2Answers: 1

    '<th></th>'+
    Sometimes something so simple and not seen. Thank you very much for your time.

  • kthorngrenkthorngren Posts: 20,140Questions: 26Answers: 4,735

    Sometimes something so simple and not seen.

    Happens to me all the time :smile:

  • jalapejalape Posts: 117Questions: 2Answers: 1

    That reassures me.
    One last thing, is this way of displaying the child table compatible with:
    responsive: true,
    http://www.javierlasen.es/easd/login/admin_nota.php

  • allanallan Posts: 61,438Questions: 1Answers: 10,049 Site admin

    Yes - you can use a modal instead for a child row (or anything else if you want to write a plug-in for Responsive to display the data somewhere else!).

    Allan

  • jalapejalape Posts: 117Questions: 2Answers: 1

    But the modal would not allow me to query two child tables at the same time.
    I've been trying to change the event that shows and hides the child table:

    $('#nota_tbl tbody').on('click', 'td.details-control', function () {
    

    By a method that I have found with the intention that when pressing the responsive button, both the hidden fields of the main table and the secondary table are shown. Perhaps this is not possible.

    siteTable.on('responsive-display', function ( e, datatable, row, showHide, update) {
    

    The reference example is: https://datatables.net/reference/event/responsive-display

  • allanallan Posts: 61,438Questions: 1Answers: 10,049 Site admin

    This is the code that Responsive uses to display a child row.

    If you want it to be displayed in something other than a modal or a child row, you'd be best to add to the $.fn.dataTable.Responsive.display object, like that code does, then you can enable your plug-in with the responsive.details.display option.

    See also the docs here for more about how Responsive displays the otherwise hidden information.

    Allan

  • jalapejalape Posts: 117Questions: 2Answers: 1

    The only way to display the child table is by using: Responsive.display.modal(). But this way I can't have two child tables open at the same time.
    With: Responsive.display.childRowImmediate, it just shows me the hidden fields from the main table. It's like allocating the space for responsive behavior and removing the rest. I can't get the child table below.

  • allanallan Posts: 61,438Questions: 1Answers: 10,049 Site admin

    Correct - if you want to use a child row for something else, then you can't also use it for Responsive. You need to use some other display technique for Responsive, such as the modal.

    Allan

  • jalapejalape Posts: 117Questions: 2Answers: 1

    I will see how I can solve this problem. If I get something I will get it.
    Thank you Allan

This discussion has been closed.