3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.grid.feature.GroupingSummary
17 * @extends Ext.grid.feature.Grouping
19 * This feature adds an aggregate summary row at the bottom of each group that is provided
20 * by the {@link Ext.grid.feature.Grouping} feature. There are 2 aspects to the summary:
24 * The summary value needs to be calculated for each column in the grid. This is controlled
25 * by the summaryType option specified on the column. There are several built in summary types,
26 * which can be specified as a string on the column configuration. These call underlying methods
29 * - {@link Ext.data.Store#count count}
30 * - {@link Ext.data.Store#sum sum}
31 * - {@link Ext.data.Store#min min}
32 * - {@link Ext.data.Store#max max}
33 * - {@link Ext.data.Store#average average}
35 * Alternatively, the summaryType can be a function definition. If this is the case,
36 * the function is called with an array of records to calculate the summary value.
40 * Similar to a column, the summary also supports a summaryRenderer function. This
41 * summaryRenderer is called before displaying a value. The function is optional, if
42 * not specified the default calculated value is shown. The summaryRenderer is called with:
44 * - value {Object} - The calculated value.
45 * - summaryData {Object} - Contains all raw summary values for the row.
46 * - field {String} - The name of the field we are calculating
50 * Ext.define('TestResult', {
51 * extend: 'Ext.data.Model',
52 * fields: ['student', 'subject', {
58 * Ext.create('Ext.grid.Panel', {
61 * renderTo: document.body,
63 * groupHeaderTpl: 'Subject: {name}',
64 * ftype: 'groupingsummary'
67 * model: 'TestResult',
68 * groupField: 'subject',
70 * student: 'Student 1',
74 * student: 'Student 1',
78 * student: 'Student 2',
82 * student: 'Student 2',
88 * dataIndex: 'student',
90 * summaryType: 'count',
91 * summaryRenderer: function(value){
92 * return Ext.String.format('{0} student{1}', value, value !== 1 ? 's' : '');
97 * summaryType: 'average'
101 Ext.define('Ext.grid.feature.GroupingSummary', {
103 /* Begin Definitions */
105 extend: 'Ext.grid.feature.Grouping',
107 alias: 'feature.groupingsummary',
110 summary: 'Ext.grid.feature.AbstractSummary'
113 /* End Definitions */
117 * Modifies the row template to include the summary row.
119 * @return {String} The modified template
121 getFeatureTpl: function() {
122 var tpl = this.callParent(arguments);
124 if (this.showSummaryRow) {
125 // lop off the end </tpl> so we can attach it
126 tpl = tpl.replace('</tpl>', '');
127 tpl += '{[this.printSummaryRow(xindex)]}</tpl>';
133 * Gets any fragments needed for the template.
135 * @return {Object} The fragments
137 getFragmentTpl: function() {
139 fragments = me.callParent();
141 Ext.apply(fragments, me.getSummaryFragments());
142 if (me.showSummaryRow) {
143 // this gets called before render, so we'll setup the data here.
144 me.summaryGroups = me.view.store.getGroups();
145 me.summaryData = me.generateSummaryData();
151 * Gets the data for printing a template row
153 * @param {Number} index The index in the template
154 * @return {Array} The template values
156 getPrintData: function(index){
158 columns = me.view.headerCt.getColumnsForTpl(),
160 length = columns.length,
162 name = me.summaryGroups[index - 1].name,
163 active = me.summaryData[name],
166 for (; i < length; ++i) {
168 column.gridSummaryValue = this.getColumnValue(column, active);
175 * Generates all of the summary data to be used when processing the template
177 * @return {Object} The summary data
179 generateSummaryData: function(){
183 store = me.view.store,
184 groupField = this.getGroupField(),
185 reader = store.proxy.reader,
186 groups = me.summaryGroups,
187 columns = me.view.headerCt.getColumnsForTpl(),
196 for (i = 0, length = groups.length; i < length; ++i) {
197 data[groups[i].name] = {};
201 * @cfg {String} remoteRoot. The name of the property
202 * which contains the Array of summary objects. Defaults to <tt>undefined</tt>.
203 * It allows to use server-side calculated summaries.
205 if (me.remoteRoot && reader.rawData) {
206 // reset reader root and rebuild extractors to extract summaries data
208 reader.root = me.remoteRoot;
209 reader.buildExtractors(true);
210 Ext.Array.each(reader.getRoot(reader.rawData), function(value) {
211 remoteData[value[groupField]] = value;
213 // restore initial reader configuration
215 reader.buildExtractors(true);
218 for (i = 0, length = columns.length; i < length; ++i) {
219 comp = Ext.getCmp(columns[i].id);
220 fieldData = me.getSummary(store, comp.summaryType, comp.dataIndex, true);
222 for (key in fieldData) {
223 if (fieldData.hasOwnProperty(key)) {
224 data[key][comp.id] = fieldData[key];
228 for (key in remoteData) {
229 if (remoteData.hasOwnProperty(key)) {
230 remote = remoteData[key][comp.dataIndex];
231 if (remote !== undefined) {
232 data[key][comp.id] = remote;