jqGrid checkbox grouping summary

303 Views Asked by At

i would like to ask somebody if is there chance to change summary in header when user will check/uncheck the checkboxes. I created function to make total sum and print it into label (for this moment i skipped solving problem with groups).

Somewhere i found some solution like discart header and generate it again, but its was just for main header, not for group headers

Here is my example code

  $(document).ready(function () {
            $("#jqGrid").jqGrid({
                url: 'data2.json',
                mtype: "GET",
                datatype: "json",
                colModel: [
                    { label: 'OrderID', name: 'OrderID', key: true, width: 75 },
      { label: 'Customer ID', name: 'CustomerID', width: 150 },
                    { label: 'Order Date', name: 'OrderDate', width: 150 },
                    {
                        label: 'Freight',
                        name: 'Freight',
                        width: 150,
                        formatter: 'number',
                        summaryTpl: "Total Units {0}", // set the summary template to show the group summary
                        summaryType: "sum" // set the formula to calculate the summary type
                    },
                    { label: 'Ship Name', name: 'ShipName', width: 150 }
                ],
                loadonce: true,
                width: 900,
                height: 500,
                rowNum: 20,
                rowList: [20, 30, 50],
                sortname: 'OrderDate',
                pager: "#jqGridPager",
                viewrecords: true,
                multiselect: true,
                grouping: true,
                userDataOnFooter: true, 
                onSelectRow: function (rowId) { handleSelectedRow(rowId); },
                groupingView: {
                    groupField: ["CustomerID"],
                    groupColumnShow: [true],
                    groupText: ["<b>{0}</b>"],
                    groupOrder: ["asc"],
                    groupSummary: [true],
                    groupSummaryPos: ['header'],
                    groupCollapse: false

                },

                gridComplete: function () {
                    currids = $(this).jqGrid('getDataIDs');
                }
            });
        });
        var totalAmt=0;
        function handleSelectedRow(id) {
           
            var jqgcell = jQuery('#jqGrid').getCell(id, 'OrderID');
            var amount = jQuery('#jqGrid').getCell(id, 'Freight');
            var cbIsChecked = jQuery("#jqg_jqGrid_" + jqgcell).prop('checked');
           
            if (cbIsChecked == true) {
                if (amount != null) {
                    totalAmt = parseInt(totalAmt) + parseInt(amount);
                }
            } else {
                if (amount != null) {
                    totalAmt = parseInt(totalAmt) - parseInt(amount);
                }
            }
            $("#price").html(totalAmt);
            

        }

2

There are 2 best solutions below

0
Tony Tomov On BEST ANSWER

I find this requirement very interesting and have prepared a demo. Of course this demo require a lot of other checking and optimizations, but it is a direction of haw to implement the requirement.

There are some notable settings and events: I assume that all rows are selected and when paging, sorting and etc we resett the selection (selectarrrow parameter) in beforeProcessing event.

The onSelectRow event is a little bit complicated, but this is required since of the current implementation.

Thanks of you, we have another directions of adding new features and improvements in Guriddo jqGrid.

Here is a demo

and below the code:

    $(document).ready(function () {
        $("#jqGrid").jqGrid({
            url: 'data.json',
            mtype: "GET",
            datatype: "json",
            colModel: [
                { label: 'OrderID', name: 'OrderID', key: true, width: 155 },
                { label: 'Customer ID', name: 'CustomerID', width: 70 },
                { label: 'Order Date', name: 'OrderDate', width: 150 },
                { 
                    label: 'Freight', 
                    name: 'Freight', 
                    width: 150,
                    formatter: 'number',
                    summaryTpl : "<b>{0}</b>",
                    summaryType: "sum"
                },
                { label: 'Employee ID', name: 'EmployeeID', width: 150 }
            ],
            loadonce:true,
            viewrecords: true,
            rowList: [20,30,50],
            width: 780,
            height: 250,
            rowNum: 20,
            multiselect : true,
            sortname: 'OrderDate',
            pager: "#jqGridPager",
            grouping: true,
            beforeProcessing: function(data) {
                // reset the seleted rows after any seoring paging and ets.
                this.p.selarrrow =[];
                // put the new rows as selected 
                for(var i=0;i<this.p.rowNum;i++) {
                    if(data.rows[i]) {
                        this.p.selarrrow.push(data.rows[i].OrderID);
                    }
                }
                return true;
            },
            preserveSelection : true,
            onSelectRow : function( rowid, status, event ) {
                var row = this.rows.namedItem( rowid );
                // determine the row index of selected row
                var index = row.rowIndex;
                // determine the level of grouping
                var groups = this.p.groupingView.groupField.length;
                // groups have specified id 
                var groupsid = this.p.id+'ghead_';
                var indexdata = [], sums=[], i;
                index--;
                // loop in reverse order to find the group headers
                while(index > 0 || (groups-1) >= 0 ) {
                    var searchid = groupsid +(groups-1);
                    // if the current id is a current group
                    if( this.rows[index] && this.rows[index].id.indexOf(searchid) !== -1) {

                        groups--;
                        // save the index of the parent group
                        indexdata[groups] = this.rows[index].rowIndex;
                        // put the sum of the Freigth (note that this is index 4)
                        sums[groups] = $(this.rows[row.rowIndex].cells[4]).text();
                    }
                    index--;
                }
                for(i=0;i<indexdata.length; i++) {
                    // fet the sum of the group
                    var suma = $(this.rows[indexdata[i]].cells[3]).text();
                    // if selected increase
                    if(status) {
                        suma = parseFloat(suma) + parseFloat(sums[i]);
                    } else {
                        suma = parseFloat(suma) - parseFloat(sums[i]) ;
                    }
                    // set the new calcculated value
                    $(this.rows[indexdata[i]].cells[3]).html( '<b>'+suma.toFixed(2)+'</b>' );
                }
            },
            groupingView: {
                groupField: ["CustomerID", "EmployeeID"],
                groupColumnShow: [true, true],
                groupText: [
                    "CustomerID: <b>{0}</b>",
                    "EmployeeID: <b>{0}</b>"
                ],
                groupOrder: ["asc", "asc"],
                groupSummary: [true, false],
                groupSummaryPos: ['header', 'header'],
                groupCollapse: false
            }
        });
    });
2
Jaroslav Chytil On

thank you for your answer and your demo is exactly what i need. I tried to continue with code which I posted and for this moment i am inphase where user get total sum just for checked records. If somebody is interested about this solution then just replace below code. + One more thing about checkboxes and updates data in grid, the main checkbox which can check/uncheck all checkboxes is little bugy with sum calculation, if user will uncheck main checkbox then sum calculation is not reseted and then you can make another sums which are counted with previous calculations. But this can be fixed in code :)

thank you for you help Tony

                    var totalAmt = 0;
                function handleSelectedRow(id) {

                    var jqgcell = jQuery('#list').getCell(id, 'id');
                    var amount = jQuery('#list').getCell(id, 'amount');
                    var cbIsChecked = jQuery("#jqg_list_" + jqgcell).prop('checked');
                    var getID = jQuery("#jqg_list_" + jqgcell).closest('tr').attr('id');

                    if (cbIsChecked == true) {
                        if (amount != null) {
                            totalAmt = parseInt(totalAmt) + parseInt(amount);

                        }
                    } else {
                        if (amount != null) {
                            totalAmt = parseInt(totalAmt) - parseInt(amount);
                        }
                    }

                    grid.jqGrid('footerData', 'set', { name: 'TOTAL', tax: totalAmt });
                    $("#price").html(totalAmt);


                }