Kal
Kal

Reputation: 2299

Group Summary Disappears When Grid is Refreshed/Re-Drawn

Back again with another ExtJS query. I have a grid with a SummaryGroup feature that is toggle-able (enabled/disabled) from a tool button on the panel header. Enabling once displays it properly, disable then try enable the feature. The grouping happens but the Summery totals of the groups doesn't come back again?

JS fiddle here: http://jsfiddle.net/hD4C4/1/

In the fiddle it will show the group totals then if you disable and re-enable again they disappear?

Here is a picture of pressing the button once: enter image description here

Here is the same grid after disabling it then re-enabling it again: enter image description here

Below is the toggle code on the panel header tool button:

 xtype: 'tool',
            type: 'expand',
            tooltip: 'Enable grouping',
            handler: function(e, target, panelHeader, tool){
                var serviceGridView = Ext.getCmp('serviceOverview').getView('groupingFeature'),
                    gridFeature = serviceGridView.getFeature('serviceOverviewGroupingFeature');
                if (tool.type == 'expand') {
                    gridFeature.enable();
                    tool.setType('collapse');
                    tool.setTooltip('Disable grouping');
                } else {
                    gridFeature.disable();
                    Ext.getCmp('serviceOverview').setLoading(false,false);
                    Ext.getCmp('serviceOverview').getStore().reload();
                    tool.setType('expand');
                    tool.setTooltip('Enable grouping');
                }
            }

And here is my grid code (with the feature function at the top:

var groupingFeature = Ext.create('Ext.grid.feature.GroupingSummary', {
    groupHeaderTpl: Ext.create('Ext.XTemplate',
        '',
        '{name:this.formatName} ({rows.length})',
        {
            formatName: function(name) {
                return '<span style="color: #3892d3;">' + name.charAt(0).toUpperCase() + name.slice(1) + '</span>';
            }
        }
    ),
    hideGroupedHeader: false,
    startCollapsed: true,
    showSummaryRow: true,
    id: 'serviceOverviewGroupingFeature'
});

Ext.define('APP.view.core.grids.Serviceoverview', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.gridportlet',

    height: 'auto',
    id: 'serviceOverview',
    cls: 'productsGrid',
    viewConfig: {
        loadMask: true
    },

    features: [groupingFeature, {ftype: 'summary'}],

    initComponent: function(){

        var store = Ext.create('APP.store.Serviceoverview');

        Ext.apply(this, {
            height: this.height,
            store: store,
            stripeRows: true,
            columnLines: true,
            columns: [{
                id       :'service-product',
                text   : 'Product',
                flex: 1,
                sortable : true,
                dataIndex: 'PACKAGE',
                summaryType: function(records) {
                    if (typeof records[0] !== 'undefined') {
                        var myGroupName = records[0].get('LISTING');

                        if (this.isStore) {
                            return '<span style="font-weight: bold;">Total of all</span>';
                        }

                        return '<span style="font-weight: bold;">'+myGroupName.charAt(0).toUpperCase() + myGroupName.slice(1)+' Totals</span>';
                        //return '<span style="font-weight: bold;">Totals</span>';
                    }
                },
                renderer: function(value, metaData ,record) {
                    return value;
                }
            },{
                id       :'service-listing',
                text   : 'Listing',
                flex: 1,
                sortable : true,
                dataIndex: 'LISTING',
                renderer: function(value, metaData ,record){
                    return value.charAt(0).toUpperCase() + value.slice(1);
                }
            },{
                id       :'service-total',
                text   : 'Running Total',
                flex: 1,
                sortable : true,
                dataIndex: 'TOTAL',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.TOTAL !== null) {
                            total += parseFloat(record.data.TOTAL);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            },{
                id       :'service-total-paid',
                text   : 'Total Paid',
                flex: 1,
                sortable : true,
                dataIndex: 'TOTAL_PAID',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.TOTAL_PAID !== null) {
                            total += parseFloat(record.data.TOTAL_PAID);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            },{
                id       :'service-outstanding',
                text   : 'Outstanding',
                flex: 1,
                sortable : true,
                dataIndex: 'OUTSTANDING',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.OUTSTANDING !== null) {
                            total += parseFloat(record.data.OUTSTANDING);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            },{
                id       :'service-properties',
                text   : 'No. of Clients',
                flex: 1,
                sortable : true,
                 dataIndex: 'CLIENTS',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.CLIENTS !== null) {
                            total += parseFloat(record.data.CLIENTS);
                        }
                    });
                    return '<span style="font-weight: bold;">' + total + '</span>';
                }
            },{
                id       :'service-average-total',
                text   : 'Av. Total',
                flex: 1,
                sortable : true,
                dataIndex: 'AVERAGE_TOTAL',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.AVERAGE_TOTAL !== null) {
                            total += parseFloat(record.data.AVERAGE_TOTAL);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            },{
                id       :'service-average-total-paid',
                text   : 'Av. Total Paid',
                flex: 1,
                sortable : true,
                dataIndex: 'AVERAGE_TOTAL_PAID',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.AVERAGE_TOTAL_PAID !== null) {
                            total += parseFloat(record.data.AVERAGE_TOTAL_PAID);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            },{
                id       :'service-average-outstanding',
                text   : 'Av. Outstanding',
                flex: 1,
                sortable : true,
                dataIndex: 'AVERAGE_OUTSTANDING',
                summaryType: function(values) {
                    var total=0.0;
                    Ext.Array.forEach(values, function (record){
                        if (record.data.AVERAGE_OUTSTANDING !== null) {
                            total += parseFloat(record.data.AVERAGE_OUTSTANDING);
                        }
                    });
                    return '<span style="font-weight: bold;">&pound;' + numeral(total.toFixed(2)).format('0,0.00') + '</span>';
                },
                renderer: function(value, metaData ,record){
                    if (value == null) {
                        return '&pound;0.00';
                    }
                    return '&pound;' + numeral(value).format('0,0.00');
                }
            }]
        });

        this.callParent(arguments);
    }
});

Thank you in advance :) Nathan

Upvotes: 2

Views: 1497

Answers (1)

Krzysztof
Krzysztof

Reputation: 16130

It looks like bug.

I have analyzed code a bit, and I discovered that this issue is caused by generateSummaryData method in feature. In this method you can find this code:

if (hasRemote || store.updating || groupInfo.lastGeneration !== group.generation) {
    record = me.populateRecord(group, groupInfo, remoteData);

    if (!lockingPartner || (me.view.ownerCt === me.view.ownerCt.ownerLockable.normalGrid)) {
        groupInfo.lastGeneration = group.generation;
    }
} else {
    record = me.getAggregateRecord(group);
}

When grid is firstly rendered first branch is executed for all groups, and after reenabling - second branch. Calling getAggregateRecord instead of populateRecord produces empty summary record. I didn't go any deeper, so for now I can only give you dirty hack to override this (it forces code to enter first branch):

store.updating = true;
feature.enable();
store.updating = false;

JSfiddle: http://jsfiddle.net/P2e7s/6/


After some more digging I've found out that most likely this issue occurs because group.generation is not incremented when populateRecord is called. As a result group.generation always equals to 1, so record is populated only when lastGeneration is empty (first code pass). After re-enabling feature, new groups are created, but they also have generation set to 1.

So I've came up with less dirty hack:

Ext.define('Ext.override.grid.feature.AbstractSummary', {
    override: 'Ext.grid.feature.GroupingSummary',
    populateRecord: function (group, groupInfo, remoteData) {
        ++group.generation;
        return this.callParent(arguments);
    }
});

With that override, you can simply enable feature, and it should work.

JSFiddle: http://jsfiddle.net/P2e7s/9/

Upvotes: 4

Related Questions