RowGroup: Creating subtotal rows with dynamic number of columns

RowGroup: Creating subtotal rows with dynamic number of columns

htwyfordhtwyford Posts: 23Questions: 9Answers: 1
edited May 2017 in Free community support

There are some docs on how to create subtotal rows here: https://datatables.net/extensions/rowgroup/examples/initialisation/customRow.html

But my table has a dynamic number of columns, so I can't have a predefined number of .append('<td>... statements at the end of the function. I tried to sum simple ints in a loop:

       <script type="text/javascript">
    $(document).ready(function () {
        var table = $('#manpower').DataTable({
            "columnDefs": [
                { "visible": false, "targets": 0 }
            ],
            order: [[0, 'asc']],
            rowGroup: {
                startRender: null,
                endRender: function (rows, group) {         
                    var container = $('<tr>');
                    container.append('<td colspan= "2"> ' + group + '</td>');
                    var i;
                    for (i = 2; i < table.columns().header().length; i++) {
                        var hourSum = rows
                            .data()
                            .pluck(i)
                            .reduce(function (a, b) {
                                return a + b * 1;
                            }, 0);
                        container.append('<td>' + hourSum + '</td>');
                    }
                    container.append('</tr>')

                    return $(container)
                },
                dataSrc: 0
            }
        });

But there is an error when I return returnString. It may have something to do with the way I'm returning the HTML object, but I'm not sure of how to construct a <tr> object the right way; I'm fairly new to JavaScript.

Any help appreciated!

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,715Questions: 1Answers: 10,108 Site admin
    Answer ✓

    Hi,

    You are constructing the HTML like a string there, but you are using jQuery so it is actually creating DOM nodes (i.e. object style rather than a string). So on line 11 you have a tr element - you don't need to then close it on 23. Try this:

       <script type="text/javascript">
    $(document).ready(function () {
        var table = $('#manpower').DataTable({
            "columnDefs": [
                { "visible": false, "targets": 0 }
            ],
            order: [[0, 'asc']],
            rowGroup: {
                startRender: null,
                endRender: function (rows, group) {        
                    var container = $('<tr/>');
                    container.append('<td colspan= "2"> ' + group + '</td>');
                    var i;
                    for (i = 2; i < table.columns().header().length; i++) {
                        var hourSum = rows
                            .data()
                            .pluck(i)
                            .reduce(function (a, b) {
                                return a + b * 1;
                            }, 0);
                        container.append('<td>' + hourSum + '</td>');
                    }
     
                    return $(container)
                },
                dataSrc: 0
            }
        });
    

    Allan

  • htwyfordhtwyford Posts: 23Questions: 9Answers: 1

    Thanks Allan! That appears to have fixed the error I was getting about unrecognized jQuery objects. One more follow up question: I now have an error on line 14 about referencing columns: Uncaught TypeError: Cannot read property 'columns' of undefined. Am I cycling through columns the wrong way?

  • htwyfordhtwyford Posts: 23Questions: 9Answers: 1

    Answering my own question here. I saw your answer in another thread about just accessing the DOM directly to get the number of columns:

    var cols =  $('#manpower thead th').length;
    for (i=2; i < cols; i++) {
    

    and that works.
    I'd still be interested in why the table.columns() approach didn't work, however!

  • allanallan Posts: 61,715Questions: 1Answers: 10,108 Site admin

    Its because the callback function is being executed before DataTables has finished initialising - i.e. at that point table is undefined!

    The rows parameter is a DataTables API instance, so you could actually use that due to how its chaining works:

    var api = rows;
    api.columns()....
    

    Allan

This discussion has been closed.