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 | }); |
---|