DataTables groupColumn - display additional column data in header row

DataTables groupColumn - display additional column data in header row

TonyRTonyR Posts: 27Questions: 6Answers: 0

I am using the groupColumn feature and it is working well. It is grouping properly on one field, the 'serial number' in an inventory database. But I would like more than the serial number to display in the header 'row', like make/model so that I can hide those columns that are repeated in the listing, even though the grouping remains only the serial number. The items for each group need only show me the last two columns, the image_id and the filename (these are for uploaded images for each serial number). Is this possible with a render function? My goal seems only cosmetic.

Javascript:

<script>
$(document).ready(function() {
    var groupColumn = 3;                    // the serial number column
    var table = $('#mainlist').DataTable( {
        dom: "Blfrtip",
        ajax: "items_images_sql.php",
        columns: [
            { data: 'item_id' },
            { data: 'maker'},
            { data: 'model'},
            { data: 'sn'},                       // the grouping column

            { data: null,                        //  Cannot group on this column
                render: function(data,type,row) {
                   return data.maker + ', Model: ' + data.model + ' s/n: ' + data.sn;
                }
            },
            { data: 'image_id'},
            { data: 'filename'}
        ],

        columnDefs: [   { visible: false, targets: [0,1,2,groupColumn] }   ],

        order: [[ groupColumn, 'asc']],
        displayLength: 20,
        drawCallback: function ( settings ) {
            var api = this.api();
            var rows = api.rows( {page:'current'}).nodes();
            var last=null;
            api.column(groupColumn, {page:'current'}).data().each( function (group,i){
                if ( last !== group) {
                    $(rows).eq( i ).before(
                        '<tr class="group"><td colspan="7"><b>Images for S/N: '
                             +group+'</b></td></tr>'
                    );
                    last = group;
                }
            });
        },

        Buttons: [
            { extend: 'collection',
                text: 'Export',
                buttons: [ 'copy', 'excel', 'csv', 'pdf', 'print']
            }
        ]
    });

    // Order by the grouping
    $('#mainlist tbody').on( 'click', 'tr.group', function () {
        var currentOrder = table.order()[0];
        if ( currentOrder[0] === groupColumn && currentOrder[1] === 'asc' ) {
            table.order( [ groupColumn, 'desc' ] ).draw();
        }
        else {
            table.order( [ groupColumn, 'asc' ] ).draw();
        }
    } );
});

</script>

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    Hi @TonyR ,

    If you want to hide more columns within the groups, just add those column numbers to the list on line 22:

    columnDefs: [   { visible: false, targets: [0,1,2,groupColumn] }
    

    The header row is created on line 15. The third parameter to columns.render is the entire row data - so you can grab that and add anything you want to that header line,

    Cheers,

    Colin

  • TonyRTonyR Posts: 27Questions: 6Answers: 0

    Hi, Colin, thanks for your response.

    In my code above, line 15 is part of a typical 'render' function to compose a normal column of data and it's not participating in a 'groupColumn.' This works fine. On line 3 I am specifying 'group on the serial number,' which also works. What I want is groupColumn = 4, not 3, but that breaks the grouping, and [object] [Object] is returned all the way down.

    I think it has something to do with the fact that my 'composed' column's data is 'null' and I am using the render function.

  • TonyRTonyR Posts: 27Questions: 6Answers: 0

    (oops, my bad: If I change the groupColunm to 4, '[object Object]' is returned on every header row)

  • colincolin Posts: 15,237Questions: 1Answers: 2,598
    Answer ✓

    Hi @TonyR ,

    Yep, apologies, my answer was a bit rubbish! If you look at this example here, you'll see that this line api.row(rows[i]).data() has all the data for the row in the loop - you can then extract the fields you want on the line two below when you build the group header,

    Hope that helps,

    Cheers,

    Colin

  • TonyRTonyR Posts: 27Questions: 6Answers: 0

    Hi, Colin,

    Thanks again for your responses! No, not rubbish; you spent the time to help and I am grateful for it. I will check the linked example and code today and report back to you. Again, thanks.

    -T

  • TonyRTonyR Posts: 27Questions: 6Answers: 0

    Colin, it worked like a charm. Many thanks for your assistance. I learned a few things along the way, too. Love that I can just tack on the name of the field, like:

                    $maker = api.row(rows[i]).data().maker;
                    $model = api.row(rows[i]).data().model;
                    if ( last !== group) {
                        $(rows).eq( i ).before(
                            '<tr class="group"><td colspan="7"><b>Images for ' + '' 
                                + 'S/N: ' + group + ', ' + $maker + ' ' 
                                + $model + '</b></td></tr>'
                        );
                        last = group;
                    }
    

    -T

This discussion has been closed.