开发者

Checkbox Selection + Grid Panel with Summary Row in ExtJS 4

given the following Grid Panel:

Ext.onReady(function() {


    var sm = new Ext.selection.CheckboxModel( {
        listeners:{
            selectionchange: function(selectionModel, selected, options){
                // Bunch of code to update store
            }
        }
    });

    var grid = Ext.create('Ext.grid.Panel', {
        features: [{
            ftype: 'summary'
        }],
        store: store,
        defaults: {               // defaults are applied to items, not the container
            sortable:true
        },
        selModel: sm,
        columns: [
            {header: 'Column 1', flex: 1, dataIndex: 'd1', summaryRenderer: function(value, summaryData, dataIndex) { return "Selected Data"} },
            {header: 'C2', width: 150, dataIndex: 'd2', summaryType: 'sum'},
            {header: 'C3', width: 150, dataIndex: 'd3', renderer: dRenderer, summaryType: 'sum'},
            {header: 'C4', width: 150, dataIndex: 'd4', rende开发者_开发百科rer: dRenderer, summaryType: 'sum'},
            {header: 'C5', width: 150, renderer: total, summaryRenderer: grandTotal}
        ],
        width: "100%",
        title: 'Grid',
        renderTo: 'grid',
        viewConfig: {
            stripeRows: true
        }
    });
});

How does this need to be refactored to summarize the data of only those rows that are selected? I know that I probably need to override the sum function of the Summary Feature, but haven't been able to find an example or proper syntax in the docs.

Thanks!

Here was my attempt at a solution (posted on the Sencha 4.x help forum w/ no responses):

Ext.define('Ext.grid.feature.SelectedSummary', {
    extend: 'Ext.grid.feature.Summary',
    alias: 'feature.selectsummary',
    generateSummaryData: function(){
        var me = this,
            data = {},
            store = me.view.store,
            selectedRecords = me.view.selModel.selected,
            columns = me.view.headerCt.getColumnsForTpl(),
            i = 0,
            length = columns.length,
            fieldData,
            key,
            comp;

        for (i = 0, length = columns.length; i < length; ++i) {
            comp = Ext.getCmp(columns[i].id);
            val = 0;
            for(j = 0, numRecs = selectedRecords.items.length; j < numRecs; j++ ) {
                field = columns[i].dataIndex;
                rec = selectedRecords.items[j];
                console.log(rec.get(field));
                val += rec.get(field);
            }
            data[comp.dataIndex] = val;//me.getSummary(store, comp.summaryType, comp.dataIndex, false);
        }
        return data;
    }
});

But this only renders correctly on initial render and only renders when I step through the code with a debugger. There's some kind of race condition where the row gets rendered without the calculations being completed.

Any ideas? Is my question too specific? Perhaps just simple pointers on writing my own feature and adding it to a Grid Panel.


Solution from a colleague:

The summary feature has the capability to take a function as the summaryType. Because the column config does not get passed to this function by default you need to define a closure that will hold on to the dataIndex.

var sm = new Ext.selection.CheckboxModel( {
    listeners:{
        selectionchange: function(selectionModel, selected, options){
            // Must refresh the view after every selection
            myGrid.getView().refresh();
            // other code for this listener
        }
    }
});

var getSelectedSumFn = function(column){
    return function(){
        var records = myGrid.getSelectionModel().getSelection(),
        result  = 0;
        Ext.each(records, function(record){
            result += record.get(column) * 1;
        });
        return result;
    };
}
// create the Grid
var myGrid = Ext.create('Ext.grid.Panel', {
    autoScroll:true,
    features: [{
        ftype: 'summary'
    }],
    store: myStore,
    defaults: {               // defaults are applied to items, not the container
        sortable:true
    },
    selModel: sm,
    columns: [
        {header: 'h0', flex: 1, dataIndex: 'groupValue'},
        {header: 'h1', width: 150, dataIndex: 'd1', summaryType: getSelectedSumFn('d1')},
        {header: 'h2', width: 150, dataIndex: 'd2', renderer: r, summaryType: getSelectedSumFn('d2')},
        {header: 'h3', width: 150, dataIndex: 'd3', renderer: r, summaryType: getSelectedSumFn('d3')},
        {header: 'h4', width: 150, dataIndex: 'd4', renderer: r, summaryType: getSelectedSumFn('d4')}
    ],
    width: "100%",
    height: "300",
    title: 'Data',
    renderTo: 'data',
    viewConfig: {
        stripeRows: true
    }
});


A little bit updated previous solution:

    var sm = new Ext.selection.CheckboxModel({
        listeners: {
            selectionchange: function (selectionModel, selected, options) {
                // Must refresh the view after every selection
                selectionModel.view.refresh();
            }
        }
    });

    var getSelectedSumFn = function (column, selModel) {
        return function () {
            var records = selModel.getSelection(),
            result = 0;
            Ext.each(records, function (record) {
                result += record.get(column) * 1;
            });
            return result;
        };
    };

and then in grid use following line:

summaryType: getSelectedSumFn('d4', sm)}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜