[619] | 1 | /* |
---|
| 2 | * Ext JS Library 2.2.1 |
---|
| 3 | * Copyright(c) 2006-2009, Ext JS, LLC. |
---|
| 4 | * licensing@extjs.com |
---|
| 5 | * |
---|
| 6 | * http://extjs.com/license |
---|
| 7 | */ |
---|
| 8 | |
---|
| 9 | Ext.grid.GroupSummary = function(config){ |
---|
| 10 | Ext.apply(this, config); |
---|
| 11 | }; |
---|
| 12 | |
---|
| 13 | Ext.extend(Ext.grid.GroupSummary, Ext.util.Observable, { |
---|
| 14 | init : function(grid){ |
---|
| 15 | this.grid = grid; |
---|
| 16 | this.cm = grid.getColumnModel(); |
---|
| 17 | this.view = grid.getView(); |
---|
| 18 | |
---|
| 19 | var v = this.view; |
---|
| 20 | v.doGroupEnd = this.doGroupEnd.createDelegate(this); |
---|
| 21 | |
---|
| 22 | v.afterMethod('onColumnWidthUpdated', this.doWidth, this); |
---|
| 23 | v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this); |
---|
| 24 | v.afterMethod('onColumnHiddenUpdated', this.doHidden, this); |
---|
| 25 | v.afterMethod('onUpdate', this.doUpdate, this); |
---|
| 26 | v.afterMethod('onRemove', this.doRemove, this); |
---|
| 27 | |
---|
| 28 | if(!this.rowTpl){ |
---|
| 29 | this.rowTpl = new Ext.Template( |
---|
| 30 | '<div class="x-grid3-summary-row" style="{tstyle}">', |
---|
| 31 | '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">', |
---|
| 32 | '<tbody><tr>{cells}</tr></tbody>', |
---|
| 33 | '</table></div>' |
---|
| 34 | ); |
---|
| 35 | this.rowTpl.disableFormats = true; |
---|
| 36 | } |
---|
| 37 | this.rowTpl.compile(); |
---|
| 38 | |
---|
| 39 | if(!this.cellTpl){ |
---|
| 40 | this.cellTpl = new Ext.Template( |
---|
| 41 | '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">', |
---|
| 42 | '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on">{value}</div>', |
---|
| 43 | "</td>" |
---|
| 44 | ); |
---|
| 45 | this.cellTpl.disableFormats = true; |
---|
| 46 | } |
---|
| 47 | this.cellTpl.compile(); |
---|
| 48 | }, |
---|
| 49 | |
---|
| 50 | toggleSummaries : function(visible){ |
---|
| 51 | var el = this.grid.getGridEl(); |
---|
| 52 | if(el){ |
---|
| 53 | if(visible === undefined){ |
---|
| 54 | visible = el.hasClass('x-grid-hide-summary'); |
---|
| 55 | } |
---|
| 56 | el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary'); |
---|
| 57 | } |
---|
| 58 | }, |
---|
| 59 | |
---|
| 60 | renderSummary : function(o, cs){ |
---|
| 61 | cs = cs || this.view.getColumnData(); |
---|
| 62 | var cfg = this.cm.config; |
---|
| 63 | |
---|
| 64 | var buf = [], c, p = {}, cf, last = cs.length-1; |
---|
| 65 | for(var i = 0, len = cs.length; i < len; i++){ |
---|
| 66 | c = cs[i]; |
---|
| 67 | cf = cfg[i]; |
---|
| 68 | p.id = c.id; |
---|
| 69 | p.style = c.style; |
---|
| 70 | p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : ''); |
---|
| 71 | if(cf.summaryType || cf.summaryRenderer){ |
---|
| 72 | p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o); |
---|
| 73 | }else{ |
---|
| 74 | p.value = ''; |
---|
| 75 | } |
---|
| 76 | if(p.value == undefined || p.value === "") p.value = " "; |
---|
| 77 | buf[buf.length] = this.cellTpl.apply(p); |
---|
| 78 | } |
---|
| 79 | |
---|
| 80 | return this.rowTpl.apply({ |
---|
| 81 | tstyle: 'width:'+this.view.getTotalWidth()+';', |
---|
| 82 | cells: buf.join('') |
---|
| 83 | }); |
---|
| 84 | }, |
---|
| 85 | |
---|
| 86 | calculate : function(rs, cs){ |
---|
| 87 | var data = {}, r, c, cfg = this.cm.config, cf; |
---|
| 88 | for(var j = 0, jlen = rs.length; j < jlen; j++){ |
---|
| 89 | r = rs[j]; |
---|
| 90 | for(var i = 0, len = cs.length; i < len; i++){ |
---|
| 91 | c = cs[i]; |
---|
| 92 | cf = cfg[i]; |
---|
| 93 | if(cf.summaryType){ |
---|
| 94 | data[c.name] = Ext.grid.GroupSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data); |
---|
| 95 | } |
---|
| 96 | } |
---|
| 97 | } |
---|
| 98 | return data; |
---|
| 99 | }, |
---|
| 100 | |
---|
| 101 | doGroupEnd : function(buf, g, cs, ds, colCount){ |
---|
| 102 | var data = this.calculate(g.rs, cs); |
---|
| 103 | buf.push('</div>', this.renderSummary({data: data}, cs), '</div>'); |
---|
| 104 | }, |
---|
| 105 | |
---|
| 106 | doWidth : function(col, w, tw){ |
---|
| 107 | var gs = this.view.getGroups(), s; |
---|
| 108 | for(var i = 0, len = gs.length; i < len; i++){ |
---|
| 109 | s = gs[i].childNodes[2]; |
---|
| 110 | s.style.width = tw; |
---|
| 111 | s.firstChild.style.width = tw; |
---|
| 112 | s.firstChild.rows[0].childNodes[col].style.width = w; |
---|
| 113 | } |
---|
| 114 | }, |
---|
| 115 | |
---|
| 116 | doAllWidths : function(ws, tw){ |
---|
| 117 | var gs = this.view.getGroups(), s, cells, wlen = ws.length; |
---|
| 118 | for(var i = 0, len = gs.length; i < len; i++){ |
---|
| 119 | s = gs[i].childNodes[2]; |
---|
| 120 | s.style.width = tw; |
---|
| 121 | s.firstChild.style.width = tw; |
---|
| 122 | cells = s.firstChild.rows[0].childNodes; |
---|
| 123 | for(var j = 0; j < wlen; j++){ |
---|
| 124 | cells[j].style.width = ws[j]; |
---|
| 125 | } |
---|
| 126 | } |
---|
| 127 | }, |
---|
| 128 | |
---|
| 129 | doHidden : function(col, hidden, tw){ |
---|
| 130 | var gs = this.view.getGroups(), s, display = hidden ? 'none' : ''; |
---|
| 131 | for(var i = 0, len = gs.length; i < len; i++){ |
---|
| 132 | s = gs[i].childNodes[2]; |
---|
| 133 | s.style.width = tw; |
---|
| 134 | s.firstChild.style.width = tw; |
---|
| 135 | s.firstChild.rows[0].childNodes[col].style.display = display; |
---|
| 136 | } |
---|
| 137 | }, |
---|
| 138 | |
---|
| 139 | // Note: requires that all (or the first) record in the |
---|
| 140 | // group share the same group value. Returns false if the group |
---|
| 141 | // could not be found. |
---|
| 142 | refreshSummary : function(groupValue){ |
---|
| 143 | return this.refreshSummaryById(this.view.getGroupId(groupValue)); |
---|
| 144 | }, |
---|
| 145 | |
---|
| 146 | getSummaryNode : function(gid){ |
---|
| 147 | var g = Ext.fly(gid, '_gsummary'); |
---|
| 148 | if(g){ |
---|
| 149 | return g.down('.x-grid3-summary-row', true); |
---|
| 150 | } |
---|
| 151 | return null; |
---|
| 152 | }, |
---|
| 153 | |
---|
| 154 | refreshSummaryById : function(gid){ |
---|
| 155 | var g = document.getElementById(gid); |
---|
| 156 | if(!g){ |
---|
| 157 | return false; |
---|
| 158 | } |
---|
| 159 | var rs = []; |
---|
| 160 | this.grid.store.each(function(r){ |
---|
| 161 | if(r._groupId == gid){ |
---|
| 162 | rs[rs.length] = r; |
---|
| 163 | } |
---|
| 164 | }); |
---|
| 165 | var cs = this.view.getColumnData(); |
---|
| 166 | var data = this.calculate(rs, cs); |
---|
| 167 | var markup = this.renderSummary({data: data}, cs); |
---|
| 168 | |
---|
| 169 | var existing = this.getSummaryNode(gid); |
---|
| 170 | if(existing){ |
---|
| 171 | g.removeChild(existing); |
---|
| 172 | } |
---|
| 173 | Ext.DomHelper.append(g, markup); |
---|
| 174 | return true; |
---|
| 175 | }, |
---|
| 176 | |
---|
| 177 | doUpdate : function(ds, record){ |
---|
| 178 | this.refreshSummaryById(record._groupId); |
---|
| 179 | }, |
---|
| 180 | |
---|
| 181 | doRemove : function(ds, record, index, isUpdate){ |
---|
| 182 | if(!isUpdate){ |
---|
| 183 | this.refreshSummaryById(record._groupId); |
---|
| 184 | } |
---|
| 185 | }, |
---|
| 186 | |
---|
| 187 | showSummaryMsg : function(groupValue, msg){ |
---|
| 188 | var gid = this.view.getGroupId(groupValue); |
---|
| 189 | var node = this.getSummaryNode(gid); |
---|
| 190 | if(node){ |
---|
| 191 | node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>'; |
---|
| 192 | } |
---|
| 193 | } |
---|
| 194 | }); |
---|
| 195 | |
---|
| 196 | Ext.grid.GroupSummary.Calculations = { |
---|
| 197 | 'sum' : function(v, record, field){ |
---|
| 198 | return v + (record.data[field]||0); |
---|
| 199 | }, |
---|
| 200 | |
---|
| 201 | 'count' : function(v, record, field, data){ |
---|
| 202 | return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1); |
---|
| 203 | }, |
---|
| 204 | |
---|
| 205 | 'max' : function(v, record, field, data){ |
---|
| 206 | var v = record.data[field]; |
---|
| 207 | var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max']; |
---|
| 208 | return v > max ? (data[field+'max'] = v) : max; |
---|
| 209 | }, |
---|
| 210 | |
---|
| 211 | 'min' : function(v, record, field, data){ |
---|
| 212 | var v = record.data[field]; |
---|
| 213 | var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min']; |
---|
| 214 | return v < min ? (data[field+'min'] = v) : min; |
---|
| 215 | }, |
---|
| 216 | |
---|
| 217 | 'average' : function(v, record, field, data){ |
---|
| 218 | var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1); |
---|
| 219 | var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0))); |
---|
| 220 | return t === 0 ? 0 : t / c; |
---|
| 221 | } |
---|
| 222 | } |
---|
| 223 | |
---|
| 224 | Ext.grid.HybridSummary = Ext.extend(Ext.grid.GroupSummary, { |
---|
| 225 | calculate : function(rs, cs){ |
---|
| 226 | var gcol = this.view.getGroupField(); |
---|
| 227 | var gvalue = rs[0].data[gcol]; |
---|
| 228 | var gdata = this.getSummaryData(gvalue); |
---|
| 229 | return gdata || Ext.grid.HybridSummary.superclass.calculate.call(this, rs, cs); |
---|
| 230 | }, |
---|
| 231 | |
---|
| 232 | updateSummaryData : function(groupValue, data, skipRefresh){ |
---|
| 233 | var json = this.grid.store.reader.jsonData; |
---|
| 234 | if(!json.summaryData){ |
---|
| 235 | json.summaryData = {}; |
---|
| 236 | } |
---|
| 237 | json.summaryData[groupValue] = data; |
---|
| 238 | if(!skipRefresh){ |
---|
| 239 | this.refreshSummary(groupValue); |
---|
| 240 | } |
---|
| 241 | }, |
---|
| 242 | |
---|
| 243 | getSummaryData : function(groupValue){ |
---|
| 244 | var json = this.grid.store.reader.jsonData; |
---|
| 245 | if(json && json.summaryData){ |
---|
| 246 | return json.summaryData[groupValue]; |
---|
| 247 | } |
---|
| 248 | return null; |
---|
| 249 | } |
---|
| 250 | }); |
---|