Extjs中GridSummary实现EditorGridPanel的合计功能

在使用gridpanel中,可以使用插件Ext.ux.grid.GroupSummary,实现分组统计,如图所示。


但通常情况下,我们也需要不进行分组统计,直接对数据进行合计显示,如下图:


这个时候,可以使用另外一个插件,Ext.ux.grid.GridSummary,使用方法与Ext.ux.grid.GroupSummary类似
,现举例如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Ext.ux.grid.GridSummary Plugin Example</title>

<title>Absolute Forms</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css"/>
<link rel="stylesheet" type="text/css" href="GroupSummary.css"/>


    <!-- GC -->
    <!-- LIBS -->
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <!-- ENDLIBS -->

    <script type="text/javascript" src="../../ext-all.js"></script>
<script src='gridsummary.js'></script><!-- Ext.ux.grid.GridSummary plugin -->

<script>
Ext.util.Format.usMoney = function(v) { // override Ext.util.usMoney
    v = Ext.num(v, 0); // ensure v is a valid numeric value, otherwise use 0 as a base (fixes $NaN.00 appearing in summaryRow when no records exist)
    v = (Math.round((v - 0) * 100)) / 100;
    v = (v == Math.floor(v)) ? v + ".00" : ((v * 10 == Math.floor(v * 10)) ? v + "0" : v);
    v = String(v);

    var ps = v.split('.');
    var whole = ps[0];
    var sub = ps[1] ? '.'+ ps[1] : '.00';
    var r = /(\d+)(\d{3})/;

    while (r.test(whole)) {
            whole = whole.replace(r, '$1' + ',' + '$2');
    }

    v = whole + sub;

    if (v.charAt(0) == '-') {
        return '-$' + v.substr(1);
    }

    return "$" + v;
}

Ext.onReady(function() {
    Ext.QuickTips.init();

    var myData = [
        ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
        ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
        ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
        ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
        ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
        ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
        ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
        ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
        ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
        ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
        ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
        ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
        ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
        ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
        ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
        ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
        ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
        ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
        ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
        ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
        ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
        ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
        ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
        ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
        ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
        ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
        ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
        ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
        ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
    ];

    // custom renderer example
    function change(val) {
        if (val > 0) {
            return '<span style="color:green;">' + val + '</span>';
        } else if (val < 0) {
            return '<span style="color:red;">' + val + '</span>';
        }
        return val;
    }

    // custom renderer example
    function pctChange(val) {
        if (val > 0) {
            return '<span style="color:green;">' + val + '%</span>';
        } else if(val < 0) {
            return '<span style="color:red;">' + val + '%</span>';
        }
        return val;
    }

    // custom summary renderer example
    function totalCompanies(v, params, data) {
            params.attr = 'ext:qtip="Total no. of companies"'; // summary column tooltip example
            return v? ((v === 0 || v > 1) ? '(' + v +' 公司)' : '(1 Company)') : '';
    }

    // custom summary renderer example
    function averageChange(v, params, data) {
            params.attr = 'ext:qtip="Average % Change"'; // summary column tooltip example
            return v? ('Average:' + v) : '';
    }



    // this could be inline, but we want to define the Company record
    // type so we can add records dynamically
    var Company = Ext.data.Record.create([
        {name: 'company'},
        {name: 'price', type: 'float'},
        {name: 'change', type: 'float'},
        {name: 'pctChange', type: 'float'},
        {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
    ]);

    // create the data store
    var store = new Ext.data.Store({
        reader: new Ext.data.ArrayReader({
            id: 0
        }, Company)
    });
  
    var summary = new Ext.ux.grid.GridSummary();

    // create the Grid
    var cm=new Ext.grid.ColumnModel([
new Ext.grid.RowNumberer(),
            {id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company', summaryType: 'count'},
            {header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price', summaryType: 'sum', editor: new Ext.form.NumberField({allowDecimals: true})},
            {header: "Change", width: 100, sortable: true, renderer: change, dataIndex: 'change', summaryType: 'average', summaryRenderer: averageChange},
            {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange', summaryType: 'min'},
            {header: "Last Updated", width: 300, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
]);

var grid = new Ext.grid.EditorGridPanel({
        renderTo: 'grid-example',
        store: store,
        cm:cm,
        plugins: [summary], // have the EditorGridPanel use the GridSummary plugin
        stripeRows: true,
        height:350,
        width:800,
        title:'Array Grid',
viewConfig:
  {
    forceFit:false,
    
deferEmptyText:false
},
        tbar: [{
            text: 'Add Company',
            handler : function() {
                var p = new Company({
                    company: 'New Company 1',
                    price: 1,
                    change: 1,
                    pctChange: 100,
                    lastChange: (new Date()).clearTime()
                });
                grid.stopEditing();
                store.insert(0, p);
                grid.startEditing(0, 0);
            }
        }]
    });

    new Ext.Button({
        renderTo: 'toggleSummary',
        text: '载入数据',
        handler: function(btn, e) {
            //summary.toggleSummary();
        store.loadData(myData);
        }
    });
});
</script>
</head>
<body scroll="no"><!-- scroll="no" to remove IE's irritating scrollbar -->
    <div id="grid-example"></div>
    <br/>
    <div id="toggleSummary"></div>
</body>
</html>


代码:

Ext.ns('Ext.ux.grid');
var debug = !false;
Ext.ux.grid.GridSummary = function(config) {
Ext.apply(this, config);
};
Ext.extend(Ext.ux.grid.GridSummary, Ext.util.Observable, {
    init : function(grid) {
        this.grid = grid;
        this.cm = grid.getColumnModel();
        this.view = grid.getView();
        
        var v = this.view;
     
        // override GridView's onLayout() method
        v.onLayout = this.onLayout;
        v.afterMethod('render', this.refreshSummary, this);
        v.afterMethod('refresh', this.refreshSummary, this);
       // v.afterMethod('syncScroll', this.syncSummaryScroll, this);
        v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
        v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
        v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
      
        // update summary row on store's add/remove/clear/update events
        grid.store.on({
            add: this.refreshSummary,
            remove: this.refreshSummary,
            clear: this.refreshSummary,
            update: this.refreshSummary,
            scope: this
        });

        if (!this.rowTpl) {
            this.rowTpl = new Ext.Template(
                '<div           style="overflow-x:hidden;"      class="x-grid3-summary-row ,x-grid3-gridsummary-row-offset" >',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr>{cells}</tr></tbody>',
                    '</table>',
                '</div>'
            );
            this.rowTpl.disableFormats = true;
        }
        this.rowTpl.compile();
        if (!this.cellTpl) {
            this.cellTpl = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
                    '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
                "</td>"
            );
            this.cellTpl.disableFormats = true;
        }
        this.cellTpl.compile();
    },

    calculate : function(rs, cm) {
        var data = {}, cfg = cm.config;
         // loop through all columns in ColumnModel
        for (var i = 0, len = cfg.length; i < len; i++) {
            var cf = cfg[i], // get column's configuration
                cname = cf.dataIndex; // get column dataIndex
            // initialise grid summary row data for the current column being
            // worked on
            data[cname] = 0;
            if (cf.summaryType) {
                for (var j = 0, jlen = rs.length; j < jlen; j++) {
                    var r = rs[j]; // get a single Record
                
                    data[cname] = Ext.ux.grid.GridSummary.Calculations[cf.summaryType](r.get(cname), r, cname, data, j);
                    
                }
            }
        }
        return data;
    },

    onLayout : function(vw, vh) {
        if (Ext.type(vh) != 'number') { // handles grid's height:'auto' config
            return;
        }
        // note: this method is scoped to the GridView
        if (!this.grid.getGridEl().hasClass('x-grid-hide-gridsummary')) {
            // readjust gridview's height only if grid summary row is visible
            this.scroller.setHeight(vh - this.summary.getHeight());
        }
    },

    syncSummaryScroll : function() {
    
        var mb = this.view.scroller.dom;
        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft;
        // second time for IE (1/2 time first fails, other browsers ignore)
        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft; 
     
        
      alert(  this.view.summaryWrap.dom.scrollLeft );
        
    },

    doWidth : function(col, w, tw) {
        var s = this.view.summary.dom;
        s.firstChild.style.width = tw;
        s.firstChild.rows[0].childNodes[col].style.width = w;
    },

    doAllWidths : function(ws, tw) {
        var s = this.view.summary.dom, wlen = ws.length;
        s.firstChild.style.width = tw;
        var cells = s.firstChild.rows[0].childNodes;
        for (var j = 0; j < wlen; j++) {
            cells[j].style.width = ws[j];
        }
    },

    doHidden : function(col, hidden, tw) {
        var s = this.view.summary.dom,
            display = hidden ? 'none' : '';
        s.firstChild.style.width = tw;
        s.firstChild.rows[0].childNodes[col].style.display = display;
    },

    renderSummary : function(o, cs, cm) {
        cs = cs || this.view.getColumnData();
        var cfg = cm.config,
            buf = [],
            last = cs.length - 1;

        for (var i = 0, len = cs.length; i < len; i++) {
            var c = cs[i], cf = cfg[i], p = {};
            p.id = c.id;
            p.style = c.style;
            p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
            var ds = this.grid.store;
            if ((cf.summaryType || cf.summaryRenderer)&&ds.getTotalCount()>0) {
                p.value = (cf.summaryRenderer || c.renderer)(o.gridData[c.name], p, o);
            } else {
                p.value = '';
            }
            if (p.value == undefined || p.value === "") p.value = "";
            buf[buf.length] = this.cellTpl.apply(
             p);
        }
        return this.rowTpl.apply({
            tstyle: 'width:' + this.view.getTotalWidth() + ';',
            cells: buf.join('')
        });
    },

    refreshSummary : function() {
        var g = this.grid, ds = g.store,
            cs = this.view.getColumnData(),
            cm = this.cm,
            rs = ds.getRange(),
            data = this.calculate(rs, cm),
            buf = this.renderSummary({gridData: data}, cs, cm);
           
        if (!this.view.summaryWrap) {
        
            this.view.summaryWrap = Ext.DomHelper.insertAfter(this.view.scroller, {
                tag: 'div',
                cls: 'x-grid3-gridsummary-row-inner'
            }, true);
            
        }
          
        this.view.summary = this.view.summaryWrap.update(buf).first();
       
         this.view.scroller.setStyle('overflow-x', 'hidden');
         var view2= this.view;
         this.view.summary.setStyle('overflow-x', 'scroll');
          this.view.summary.on("scroll"   ,function(){
          
          
           view2.scroller.dom.scrollLeft=view2.summary.dom.scrollLeft
          }
           );
          },
  

    toggleSummary : function(visible) { // true to display summary row
        var el = this.grid.getGridEl();

        if (el) {
            if (visible === undefined) {
                visible = el.hasClass('x-grid-hide-gridsummary');
            }
            el[visible ? 'removeClass' : 'addClass']('x-grid-hide-gridsummary');

            this.view.layout(); // readjust gridview height
        }
    },

    getSummaryNode : function() {
        return this.view.summary
    }
});
Ext.reg('gridsummary', Ext.ux.grid.GridSummary);

Ext.ux.grid.GridSummary.Calculations = {
    sum : function(v, record, colName, data, rowIdx) {
        return data[colName] + Ext.num(v, 0);
    },

    count : function(v, record, colName, data, rowIdx) {
        return rowIdx + 1;
    },

    max : function(v, record, colName, data, rowIdx) {
        return Math.max(Ext.num(v, 0), data[colName]);
    },

    min : function(v, record, colName, data, rowIdx) {
        return Math.min(Ext.num(v, 0), data[colName]);
    },

    average : function(v, record, colName, data, rowIdx) {
        var t = data[colName] + Ext.num(v, 0), count = record.store.getCount();
        return rowIdx == count - 1 ? (t / count) : t;
    }  
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值