Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Grid Summary Plugin

  1. #1
    Ext User
    Join Date
    Jun 2007
    Posts
    66
    Vote Rating
    0
      0  

    Default Grid Summary Plugin

    I needed a way to add a summary row to a grid. This is similar to (and adapted from) the GroupSummary from the samples. Here are the situations when this might be useful:
    • Table summary needed, but not using grouping.
    • Not using paging (entire table shown)
    This plugin seems to work fine for me. If anyone has ways to improve or make it more efficient, then please speak up.
    Use the same css styles from the sample:
    Code:
    .x-grid3-summary-row {background:#F1F2F4 none repeat scroll 0%;color:#333333;border:1px solid #ededed;border-top-color:#fff;}
    .x-grid3-summary-row .x-grid3-cell-inner {font-weight:bold;padding-bottom:4px;}
    .x-grid3-cell-first .x-grid3-cell-inner {padding-left:16px;}
    .x-grid-hide-summary .x-grid3-summary-row {display:none;}
    .x-grid3-summary-msg {font-weight:bold;padding:4px 16px;}
    the plugin code:
    Code:
    Ext.grid.GridSummary = function(config){
        Ext.apply(this, config);
    };
    
    Ext.extend(Ext.grid.GridSummary, Ext.util.Observable, {
        init : function(grid){
            this.grid = grid;
            this.cm = grid.getColumnModel();
            this.view = grid.getView();
            this.beforeInsert = false;
    
            var v = this.view;
            this.doRenderBase = v.doRender;
            v.doRender = this.doRender.createDelegate(this);
            
            v.beforeMethod('insertRows',this.doBeforeInsert,this);
            v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
            v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
            v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
            v.afterMethod('onUpdate', this.doUpdate, this);
            v.afterMethod('onRemove', this.doRemove, this);
    
            if(!this.rowTpl){
                this.rowTpl = new Ext.Template(
                    '<div class="x-grid3-summary-row" style="{tstyle}">',
                    '<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">{value}</div>',
                    "</td>"
                );
                this.cellTpl.disableFormats = true;
            }
            this.cellTpl.compile();
        },
    
        toggleSummaries : function(visible){
            var el = this.grid.getGridEl();
            if(el){
                if(visible === undefined){
                    visible = el.hasClass('x-grid-hide-summary');
                }
                el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary');
            }
        },
    
        renderSummary : function(o, cs){
            cs = cs || this.view.getColumnData();
            var cfg = this.cm.config;
    
            var buf = [], c, p = {}, cf, last = cs.length-1;
            for(var i = 0, len = cs.length; i < len; i++){
                c = cs[i];
                cf = cfg[i];
                p.id = c.id;
                p.style = c.style;
                p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
                if(cf.summaryType || cf.summaryRenderer){
                    p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
                }else{
                    p.value = '';
                }
                if(p.value == undefined || p.value === "") p.value = "&#160;";
                buf[buf.length] = this.cellTpl.apply(p);
            }
    
            return this.rowTpl.apply({
                tstyle: 'width:'+this.view.getTotalWidth()+';',
                cells: buf.join('')
            });
        },
    
        calculate : function(rs, cs){
            var data = {}, r, c, cfg = this.cm.config, cf;
            for(var j = 0, jlen = rs.length; j < jlen; j++){
                r = rs[j];
                for(var i = 0, len = cs.length; i < len; i++){
                    c = cs[i];
                    cf = cfg[i];
                    if(cf.summaryType){
                        data[c.name] = Ext.grid.GridSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data);
                    }
                }
            }
            return data;
        },
    
        doRender : function(cs, rs, ds, startRow, colCount, stripe){
            var buf = this.doRenderBase.call(this.view,cs, rs, ds, startRow, colCount, stripe);
            // We normally don't want to add summary row to every insert.
            // However, we do need to if this is the first row
            if (!this.beforeInsert || this.view.getRows().length==0){
                var data = this.calculate(rs, cs);
                buf += this.renderSummary({data: data}, cs);
            } else {
                this.refreshSummary();
            }
            this.beforeInsert = false;
            return buf;
        },
    
        doWidth : function(col, w, tw){
            var gs = this.view.getRows(), s;
            if (gs.length > 0){
                s = gs[gs.length - 1];
                s.style.width = tw;
                s.firstChild.style.width = tw;
                s.firstChild.rows[0].childNodes[col].style.width = w;
            }
        },
    
        doAllWidths : function(ws, tw){
            var gs = this.view.getRows(), s, cells, wlen = ws.length;
            if (gs.length > 0) {
                s = gs[gs.length - 1];
                s.style.width = tw;
                s.firstChild.style.width = tw;
                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 gs = this.view.getRows(), s, display = hidden ? 'none' : '';
            for(var i = 0, len = gs.length; i < len; i++){
                s = gs[i].childNodes[2];
                s.style.width = tw;
                s.firstChild.style.width = tw;
                s.firstChild.rows[0].childNodes[col].style.display = display;
            }
        },
    
        getSummaryNode : function(){
            return this.view.el.child('.x-grid3-summary-row');
        },
    
        refreshSummary : function(){
            var rs = [];
            this.grid.store.each(function(r){
                rs[rs.length] = r;
            });
            var cs = this.view.getColumnData();
            var data = this.calculate(rs, cs);
            var markup = this.renderSummary({data: data}, cs);
            var body = this.view.el.child('.x-grid3-body').dom;
    
            var existing = this.getSummaryNode();
            if(existing){
                body.removeChild(existing.dom);
            }
            Ext.DomHelper.append(body, markup);
            return true;
        },
        
        removeSummary : function(){
            var existing = this.getSummaryNode();
            if (existing) {
                var body = this.view.el.child('.x-grid3-body').dom;
                body.removeChild(existing.dom);
            }
        },
    
        doUpdate : function(ds, record){
            this.refreshSummary();
        },
    
        doRemove : function(ds, record, index, isUpdate){
            if(!isUpdate){
                if (ds.getCount() === 0) this.removeSummary();
                else this.refreshSummary();
            }
        },
    
        doBeforeInsert : function(){
            this.beforeInsert = true;
        }
    });
    
    Ext.grid.GridSummary.Calculations = {
        'sum' : function(v, record, field){
            return v + (record.data[field]||0);
        },
    
        'count' : function(v, record, field, data){
            return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
        },
    
        'max' : function(v, record, field, data){
            var v = record.data[field];
            var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max'];
            return v > max ? (data[field+'max'] = v) : max;
        },
    
        'min' : function(v, record, field, data){
            var v = record.data[field];
            var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min'];
            return v < min ? (data[field+'min'] = v) : min;
        },
    
        'average' : function(v, record, field, data){
            var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
            var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0)));
            return t === 0 ? 0 : t / c;
        }
    }
    Last edited by cutigersfan; 20 Dec 2007 at 3:53 AM. Reason: Code update

  2. #2
    Ext User
    Join Date
    Apr 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default

    good,it seems very nice!!!

  3. #3
    Ext User
    Join Date
    Apr 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default

    if the summary row can be fixed to bottom,that will be perfect!!

  4. #4
    Ext User
    Join Date
    Jun 2007
    Posts
    66
    Vote Rating
    0
      0  

    Default yes

    The summary row should be on the bottom.

  5. #5
    Ext User
    Join Date
    Nov 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default

    Just a note, if the grid becomes grouped, I get JS errors. Do you want me to post or is it not expected to work when grouped?

  6. #6
    Ext User tinker's Avatar
    Join Date
    Sep 2007
    Posts
    26
    Vote Rating
    1
      0  

    Thumbs up Good work!

    Hey! Good Work!

    I guess I looked at it late or maybe could not wait for someone to make this plugin!!!

    I noticed that readers have requested for the summary row to be fixed - I had my own version of GridSummary that has this feature... just thought it my be helpful.

    Check it out here

    Happy Scripting!

  7. #7
    Sencha User galdaka's Avatar
    Join Date
    Mar 2007
    Location
    Spain
    Posts
    1,166
    Vote Rating
    0
      0  

    Default

    Live example for testing?

    Thanks in advance,

  8. #8
    Ext User
    Join Date
    Jun 2007
    Posts
    66
    Vote Rating
    0
      0  

    Default No

    Quote Originally Posted by JeffG View Post
    Just a note, if the grid becomes grouped, I get JS errors. Do you want me to post or is it not expected to work when grouped?

    No, I stated in my original post that I didn't intend for this to be used when grouping is desired. It probably won't work in that situation. I didn't need grouping for my purposes.

  9. #9
    Ext User
    Join Date
    Jun 2007
    Posts
    66
    Vote Rating
    0
      0  

    Default

    Quote Originally Posted by tinker View Post
    Hey! Good Work!

    I guess I looked at it late or maybe could not wait for someone to make this plugin!!!

    I noticed that readers have requested for the summary row to be fixed - I had my own version of GridSummary that has this feature... just thought it my be helpful.

    Check it out here

    Happy Scripting!

    I tried your version and it seems to work the same as mine. I have made a update or two since original posting. I wasn't able to test grouping as it wasn't in my original design.
    Last edited by cutigersfan; 20 Dec 2007 at 12:05 PM. Reason: spelling

  10. #10
    Ext User piskui07's Avatar
    Join Date
    Oct 2007
    Posts
    63
    Vote Rating
    0
      0  

    Default

    It seems nice... but... can you post some screenshot or... (best) a live example or ready_to_use_example zip?

    Thanks in advance.
    Bye

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •