1. #1
    Sencha User krause's Avatar
    Join Date
    Jun 2008
    Posts
    53
    Vote Rating
    0
    krause is on a distinguished road

      0  

    Post [2.*,3.*] GroupSummary + Grid.reconfigure Error

    [2.*,3.*] GroupSummary + Grid.reconfigure Error


    Ext.grid.GroupSummary which is in examples/grid (btw why isn't it part of ext-all?) has errors when used in a dynamic grid which needs to be reconfigured (i.e. when you need to change the column model and store at runtime based on the server's data). The error manifests itself as "cf is undefined" on line 93: if(cf.summaryType){

    The problem seems to be that the column model is being accessed through this.cm instead of using the grid's getColumnModel(), since this.cm doesn't change after the grid has been reconfigured with a different column model.

    The fix that worked for me was to change all references of this.cm by this.grid.getColumnModel() (there are only 3 such references, inside init, inside renderSummary and inside calculate).

    Resulting fixed code (changes highlighted in red):
    Code:
    /*
     * Ext JS Library 2.2
     * Copyright(c) 2006-2008, Ext JS, LLC.
     * licensing@extjs.com
     * 
     * http://extjs.com/license
     */
    
    Ext.grid.GroupSummary = function(config){
        Ext.apply(this, config);
    };
    
    Ext.extend(Ext.grid.GroupSummary, Ext.util.Observable, {
        init : function(grid){
            this.grid = grid;
            //this.cm = grid.getColumnModel(); <-- Not needed anymore
            this.view = grid.getView();
    
            var v = this.view;
            v.doGroupEnd = this.doGroupEnd.createDelegate(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;                    <-- Original
            var cfg = this.grid.getColumnModel().config; // <-- Fixed
    
            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 = " ";
                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;   <-- Original
            var data = {}, r, c, cfg = this.grid.getColumnModel().config, cf;  // <-- Fixed
            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.GroupSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data);
                    }
                }
            }
            return data;
        },
    
        doGroupEnd : function(buf, g, cs, ds, colCount){
            var data = this.calculate(g.rs, cs);
            buf.push('</div>', this.renderSummary({data: data}, cs), '</div>');
        },
    
        doWidth : function(col, w, tw){
            var gs = this.view.getGroups(), s;
            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.width = w;
            }
        },
    
        doAllWidths : function(ws, tw){
            var gs = this.view.getGroups(), s, cells, wlen = ws.length;
            for(var i = 0, len = gs.length; i < len; i++){
                s = gs[i].childNodes[2];
                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.getGroups(), 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;
            }
        },
    
        // Note: requires that all (or the first) record in the 
        // group share the same group value. Returns false if the group
        // could not be found.
        refreshSummary : function(groupValue){
            return this.refreshSummaryById(this.view.getGroupId(groupValue));
        },
    
        getSummaryNode : function(gid){
            var g = Ext.fly(gid, '_gsummary');
            if(g){
                return g.down('.x-grid3-summary-row', true);
            }
            return null;
        },
    
        refreshSummaryById : function(gid){
            var g = document.getElementById(gid);
            if(!g){
                return false;
            }
            var rs = [];
            this.grid.store.each(function(r){
                if(r._groupId == gid){
                    rs[rs.length] = r;
                }
            });
            var cs = this.view.getColumnData();
            var data = this.calculate(rs, cs);
            var markup = this.renderSummary({data: data}, cs);
    
            var existing = this.getSummaryNode(gid);
            if(existing){
                g.removeChild(existing);
            }
            Ext.DomHelper.append(g, markup);
            return true;
        },
    
        doUpdate : function(ds, record){
            this.refreshSummaryById(record._groupId);
        },
    
        doRemove : function(ds, record, index, isUpdate){
            if(!isUpdate){
                this.refreshSummaryById(record._groupId);
            }
        },
    
        showSummaryMsg : function(groupValue, msg){
            var gid = this.view.getGroupId(groupValue);
            var node = this.getSummaryNode(gid);
            if(node){
                node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>';
            }
        }
    });
    
    Ext.grid.GroupSummary.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;
        }
    }
    
    Ext.grid.HybridSummary = Ext.extend(Ext.grid.GroupSummary, {
        calculate : function(rs, cs){
            var gcol = this.view.getGroupField();
            var gvalue = rs[0].data[gcol];
            var gdata = this.getSummaryData(gvalue);
            return gdata || Ext.grid.HybridSummary.superclass.calculate.call(this, rs, cs);
        },
    
        updateSummaryData : function(groupValue, data, skipRefresh){
            var json = this.grid.store.reader.jsonData;
            if(!json.summaryData){
                json.summaryData = {};
            }
            json.summaryData[groupValue] = data;
            if(!skipRefresh){
                this.refreshSummary(groupValue);
            }
        },
    
        getSummaryData : function(groupValue){
            var json = this.grid.store.reader.jsonData;
            if(json && json.summaryData){
                return json.summaryData[groupValue];
            }
            return null;
        }
    });

  2. #2
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,664
    Vote Rating
    584
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    This has already been fixed in the 3.x branch, I'll commit the same to 2.x.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

Thread Participants: 1