3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">Ext.ns('Ext.ux.grid');
\r
10 <div id="cls-Ext.ux.grid.GroupSummary"></div>/**
\r
11 * @class Ext.ux.grid.GroupSummary
\r
12 * @extends Ext.util.Observable
\r
13 * A GridPanel plugin that enables dynamic column calculations and a dynamically
\r
14 * updated grouped summary row.
\r
16 Ext.ux.grid.GroupSummary = Ext.extend(Ext.util.Observable, {
\r
17 <div id="cfg-Ext.ux.grid.GroupSummary-summaryRenderer"></div>/**
\r
18 * @cfg {Function} summaryRenderer Renderer example:<pre><code>
\r
19 summaryRenderer: function(v, params, data){
\r
20 return ((v === 0 || v > 1) ? '(' + v +' Tasks)' : '(1 Task)');
\r
24 <div id="cfg-Ext.ux.grid.GroupSummary-summaryType"></div>/**
\r
25 * @cfg {String} summaryType (Optional) The type of
\r
26 * calculation to be used for the column. For options available see
\r
27 * {@link #Calculations}.
\r
30 constructor : function(config){
\r
31 Ext.apply(this, config);
\r
32 Ext.ux.grid.GroupSummary.superclass.constructor.call(this);
\r
34 init : function(grid){
\r
36 this.cm = grid.getColumnModel();
\r
37 this.view = grid.getView();
\r
40 v.doGroupEnd = this.doGroupEnd.createDelegate(this);
\r
42 v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
\r
43 v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
\r
44 v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
\r
45 v.afterMethod('onUpdate', this.doUpdate, this);
\r
46 v.afterMethod('onRemove', this.doRemove, this);
\r
49 this.rowTpl = new Ext.Template(
\r
50 '<div class="x-grid3-summary-row" style="{tstyle}">',
\r
51 '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
\r
52 '<tbody><tr>{cells}</tr></tbody>',
\r
55 this.rowTpl.disableFormats = true;
\r
57 this.rowTpl.compile();
\r
60 this.cellTpl = new Ext.Template(
\r
61 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
\r
62 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on">{value}</div>',
\r
65 this.cellTpl.disableFormats = true;
\r
67 this.cellTpl.compile();
\r
70 <div id="method-Ext.ux.grid.GroupSummary-toggleSummaries"></div>/**
\r
71 * Toggle the display of the summary row on/off
\r
72 * @param {Boolean} visible <tt>true</tt> to show the summary, <tt>false</tt> to hide the summary.
\r
74 toggleSummaries : function(visible){
\r
75 var el = this.grid.getGridEl();
\r
77 if(visible === undefined){
\r
78 visible = el.hasClass('x-grid-hide-summary');
\r
80 el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary');
\r
84 renderSummary : function(o, cs){
\r
85 cs = cs || this.view.getColumnData();
\r
86 var cfg = this.cm.config;
\r
88 var buf = [], c, p = {}, cf, last = cs.length-1;
\r
89 for(var i = 0, len = cs.length; i < len; i++){
\r
94 p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
\r
95 if(cf.summaryType || cf.summaryRenderer){
\r
96 p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
\r
100 if(p.value == undefined || p.value === "") p.value = " ";
\r
101 buf[buf.length] = this.cellTpl.apply(p);
\r
104 return this.rowTpl.apply({
\r
105 tstyle: 'width:'+this.view.getTotalWidth()+';',
\r
106 cells: buf.join('')
\r
112 * @param {Object} rs
\r
113 * @param {Object} cs
\r
115 calculate : function(rs, cs){
\r
116 var data = {}, r, c, cfg = this.cm.config, cf;
\r
117 for(var j = 0, jlen = rs.length; j < jlen; j++){
\r
119 for(var i = 0, len = cs.length; i < len; i++){
\r
122 if(cf.summaryType){
\r
123 data[c.name] = Ext.ux.grid.GroupSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data);
\r
130 doGroupEnd : function(buf, g, cs, ds, colCount){
\r
131 var data = this.calculate(g.rs, cs);
\r
132 buf.push('</div>', this.renderSummary({data: data}, cs), '</div>');
\r
135 doWidth : function(col, w, tw){
\r
136 var gs = this.view.getGroups(), s;
\r
137 for(var i = 0, len = gs.length; i < len; i++){
\r
138 s = gs[i].childNodes[2];
\r
139 s.style.width = tw;
\r
140 s.firstChild.style.width = tw;
\r
141 s.firstChild.rows[0].childNodes[col].style.width = w;
\r
145 doAllWidths : function(ws, tw){
\r
146 var gs = this.view.getGroups(), s, cells, wlen = ws.length;
\r
147 for(var i = 0, len = gs.length; i < len; i++){
\r
148 s = gs[i].childNodes[2];
\r
149 s.style.width = tw;
\r
150 s.firstChild.style.width = tw;
\r
151 cells = s.firstChild.rows[0].childNodes;
\r
152 for(var j = 0; j < wlen; j++){
\r
153 cells[j].style.width = ws[j];
\r
158 doHidden : function(col, hidden, tw){
\r
159 var gs = this.view.getGroups(), s, display = hidden ? 'none' : '';
\r
160 for(var i = 0, len = gs.length; i < len; i++){
\r
161 s = gs[i].childNodes[2];
\r
162 s.style.width = tw;
\r
163 s.firstChild.style.width = tw;
\r
164 s.firstChild.rows[0].childNodes[col].style.display = display;
\r
168 // Note: requires that all (or the first) record in the
\r
169 // group share the same group value. Returns false if the group
\r
170 // could not be found.
\r
171 refreshSummary : function(groupValue){
\r
172 return this.refreshSummaryById(this.view.getGroupId(groupValue));
\r
175 getSummaryNode : function(gid){
\r
176 var g = Ext.fly(gid, '_gsummary');
\r
178 return g.down('.x-grid3-summary-row', true);
\r
183 refreshSummaryById : function(gid){
\r
184 var g = document.getElementById(gid);
\r
189 this.grid.store.each(function(r){
\r
190 if(r._groupId == gid){
\r
194 var cs = this.view.getColumnData();
\r
195 var data = this.calculate(rs, cs);
\r
196 var markup = this.renderSummary({data: data}, cs);
\r
198 var existing = this.getSummaryNode(gid);
\r
200 g.removeChild(existing);
\r
202 Ext.DomHelper.append(g, markup);
\r
206 doUpdate : function(ds, record){
\r
207 this.refreshSummaryById(record._groupId);
\r
210 doRemove : function(ds, record, index, isUpdate){
\r
212 this.refreshSummaryById(record._groupId);
\r
216 <div id="method-Ext.ux.grid.GroupSummary-showSummaryMsg"></div>/**
\r
217 * Show a message in the summary row.
\r
219 grid.on('afteredit', function(){
\r
220 var groupValue = 'Ext Forms: Field Anchoring';
\r
221 summary.showSummaryMsg(groupValue, 'Updating Summary...');
\r
224 * @param {String} groupValue
\r
225 * @param {String} msg Text to use as innerHTML for the summary row.
\r
227 showSummaryMsg : function(groupValue, msg){
\r
228 var gid = this.view.getGroupId(groupValue);
\r
229 var node = this.getSummaryNode(gid);
\r
231 node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>';
\r
237 Ext.grid.GroupSummary = Ext.ux.grid.GroupSummary;
\r
240 <div id="prop-Ext.ux.grid.GroupSummary-Calculations"></div>/**
\r
241 * Calculation types for summary row:</p><div class="mdetail-params"><ul>
\r
242 * <li><b><tt>sum</tt></b> : <div class="sub-desc"></div></li>
\r
243 * <li><b><tt>count</tt></b> : <div class="sub-desc"></div></li>
\r
244 * <li><b><tt>max</tt></b> : <div class="sub-desc"></div></li>
\r
245 * <li><b><tt>min</tt></b> : <div class="sub-desc"></div></li>
\r
246 * <li><b><tt>average</tt></b> : <div class="sub-desc"></div></li>
\r
248 * <p>Custom calculations may be implemented. An example of
\r
249 * custom <code>summaryType=totalCost</code>:</p><pre><code>
\r
250 // define a custom summary function
\r
251 Ext.ux.grid.GroupSummary.Calculations['totalCost'] = function(v, record, field){
\r
252 return v + (record.data.estimate * record.data.rate);
\r
255 * @property Calculations
\r
258 Ext.ux.grid.GroupSummary.Calculations = {
\r
259 'sum' : function(v, record, field){
\r
260 return v + (record.data[field]||0);
\r
263 'count' : function(v, record, field, data){
\r
264 return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
\r
267 'max' : function(v, record, field, data){
\r
268 var v = record.data[field];
\r
269 var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max'];
\r
270 return v > max ? (data[field+'max'] = v) : max;
\r
273 'min' : function(v, record, field, data){
\r
274 var v = record.data[field];
\r
275 var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min'];
\r
276 return v < min ? (data[field+'min'] = v) : min;
\r
279 'average' : function(v, record, field, data){
\r
280 var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
\r
281 var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0)));
\r
282 return t === 0 ? 0 : t / c;
\r
285 Ext.grid.GroupSummary.Calculations = Ext.ux.grid.GroupSummary.Calculations;
\r
287 <div id="cls-Ext.ux.grid.HybridSummary"></div>/**
\r
288 * @class Ext.ux.grid.HybridSummary
\r
289 * @extends Ext.ux.grid.GroupSummary
\r
290 * Adds capability to specify the summary data for the group via json as illustrated here:
\r
295 projectId: 100, project: 'House',
\r
296 taskId: 112, description: 'Paint',
\r
297 estimate: 6, rate: 150,
\r
305 description: 14, estimate: 9,
\r
306 rate: 99, due: new Date(2009, 6, 29),
\r
314 Ext.ux.grid.HybridSummary = Ext.extend(Ext.ux.grid.GroupSummary, {
\r
317 * @param {Object} rs
\r
318 * @param {Object} cs
\r
320 calculate : function(rs, cs){
\r
321 var gcol = this.view.getGroupField();
\r
322 var gvalue = rs[0].data[gcol];
\r
323 var gdata = this.getSummaryData(gvalue);
\r
324 return gdata || Ext.ux.grid.HybridSummary.superclass.calculate.call(this, rs, cs);
\r
327 <div id="method-Ext.ux.grid.HybridSummary-updateSummaryData"></div>/**
\r
329 grid.on('afteredit', function(){
\r
330 var groupValue = 'Ext Forms: Field Anchoring';
\r
331 summary.showSummaryMsg(groupValue, 'Updating Summary...');
\r
332 setTimeout(function(){ // simulate server call
\r
333 // HybridSummary class implements updateSummaryData
\r
334 summary.updateSummaryData(groupValue,
\r
335 // create data object based on configured dataIndex
\r
336 {description: 22, estimate: 888, rate: 888, due: new Date(), cost: 8});
\r
340 * @param {String} groupValue
\r
341 * @param {Object} data data object
\r
342 * @param {Boolean} skipRefresh (Optional) Defaults to false
\r
344 updateSummaryData : function(groupValue, data, skipRefresh){
\r
345 var json = this.grid.store.reader.jsonData;
\r
346 if(!json.summaryData){
\r
347 json.summaryData = {};
\r
349 json.summaryData[groupValue] = data;
\r
351 this.refreshSummary(groupValue);
\r
355 <div id="method-Ext.ux.grid.HybridSummary-getSummaryData"></div>/**
\r
356 * Returns the summaryData for the specified groupValue or null.
\r
357 * @param {String} groupValue
\r
358 * @return {Object} summaryData
\r
360 getSummaryData : function(groupValue){
\r
361 var json = this.grid.store.reader.jsonData;
\r
362 if(json && json.summaryData){
\r
363 return json.summaryData[groupValue];
\r
370 Ext.grid.HybridSummary = Ext.ux.grid.HybridSummary;
\r