Tom Hartwell
Tom Hartwell

Reputation: 668

ExtJS 4 - Refreshing Summary Feature of Grid Panel Without Refreshing Entire View

I'm using ExtJS's GridPanel library to render a list of rows that have a CheckboxModel for selections. There is also a summary row that adds up all of the selected data and displays it in a row at the bottom of the GridPanel. The code for this is:

var sm = Ext.create('Ext.selection.CheckboxModel', {

    /////////
    // With large number of rows ... this takes forever
    /////////
    grid.getView().refresh();
    /////////
    /////////


    listeners:{
        selectionchange: function(selectionModel, selectedRecords, options){
          // Do stuff

        }
    }
});

var selSumFn = function(column, selModel){
    return function(){
        var records = selModel.getSelection(),
        result  = 0;
        //console.log("records:" + records.length);
        Ext.each(records, function(record){
            result += record.get(column) * 1;
        });

        return result;
    };
};

var grid = Ext.create('Ext.grid.Panel', {
    autoScroll:true,
    features: [{
        ftype: 'summary'
    }],
    store: store,
    defaults: {
        sortable:true
    },
    selModel: sm,
    columns: [
        {header: 'Column 1', width: 100, dataIndex: 'col1', summaryType: selSumFn('col1', sm)},
        {header: 'Column 2', width: 100, dataIndex: 'col2', summaryType: selSumFn('col2', sm)}
    ],
    width: 730,
    height: 400 ,
    title: 'Data',
    renderTo: 'data-div',
    viewConfig: {
        stripeRows: true
    },
    listeners: {'beforerender' : {fn:function(){this.store.load();}}}
});

Is there any way to only refresh the summaryrow feature and not the entire view? Refreshing the view was the only way I could find to refresh the summary row when updates were made to checkbox selections of the GridPanel.

Upvotes: 1

Views: 8868

Answers (2)

Roberto
Roberto

Reputation: 1

If you are using GroupingSummary, you need to use this instead:

refresh:function(){

    var rowEls = this.view.el.query('tr.x-grid-row-summary');
    var i = 1;
    Ext.Array.each(this.summaryGroups, function(group){

        var tpl = new Ext.XTemplate(
            this.printSummaryRow(i),
            this.getFragmentTpl()
          );

        tpl.overwrite(rowEls[i-1], {})

        i++;
    },this);

Upvotes: 0

mistaecko
mistaecko

Reputation: 2685

There is no support for this in Ext 4.0.2a. The grid view builds a single view template with features adding or modifying this template via a multitude of defined hooks. The result is a single template instance that cannot be easily dissected.

The best solution I found is to rebuild the template fragment that renders the summary row mimicking what the grid view is doing during the template construction process. Then overwrite the existing DOM for the summary row with a freshly rendered version.

I have created a patch (as an override) that adds a refresh() method to the Summary feature. The code turned out to be surprisingly slick.

Ext.require('Ext.grid.feature.Summary', function() {
    Ext.override(Ext.grid.feature.Summary, {
        refresh: function() {
            if(this.view.rendered) {
                var tpl = Ext.create(
                            'Ext.XTemplate',
                            '{[this.printSummaryRow()]}',
                            this.getFragmentTpl()
                          );
                tpl.overwrite(this.getRowEl(), {});
            }
        },

        getRowEl: function() {
            return this.view.el.down('tr.x-grid-row-summary');
        }
    });
});

In your selectionchange listener:

selectionchange: function(selectionModel, selectedRecords, options) {
    grid.getView().getFeature(0).refresh();
}

See this JsFiddle for a live demo.

Of course this might break in future versions of Ext. However, it could turn out to be quite robust since it delegates most of its work to existing methods.

Upvotes: 6

Related Questions