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 two 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
51 * Ext.define('TestResult', {
52 * extend: 'Ext.data.Model',
53 * fields: ['student', 'subject', {
59 * Ext.create('Ext.grid.Panel', {
62 * renderTo: document.body,
64 * groupHeaderTpl: 'Subject: {name}',
65 * ftype: 'groupingsummary'
68 * model: 'TestResult',
69 * groupField: 'subject',
71 * student: 'Student 1',
75 * student: 'Student 1',
79 * student: 'Student 2',
83 * student: 'Student 2',
89 * dataIndex: 'student',
91 * summaryType: 'count',
92 * summaryRenderer: function(value){
93 * return Ext.String.format('{0} student{1}', value, value !== 1 ? 's' : '');
98 * summaryType: 'average'
102 Ext.define('Ext.grid.feature.GroupingSummary', {
104 /* Begin Definitions */
106 extend: 'Ext.grid.feature.Grouping',
108 alias: 'feature.groupingsummary',
111 summary: 'Ext.grid.feature.AbstractSummary'
114 /* End Definitions */
118 * Modifies the row template to include the summary row.
120 * @return {String} The modified template
122 getFeatureTpl: function() {
123 var tpl = this.callParent(arguments);
125 if (this.showSummaryRow) {
126 // lop off the end </tpl> so we can attach it
127 tpl = tpl.replace('</tpl>', '');
128 tpl += '{[this.printSummaryRow(xindex)]}</tpl>';
134 * Gets any fragments needed for the template.
136 * @return {Object} The fragments
138 getFragmentTpl: function() {
140 fragments = me.callParent();
142 Ext.apply(fragments, me.getSummaryFragments());
143 if (me.showSummaryRow) {
144 // this gets called before render, so we'll setup the data here.
145 me.summaryGroups = me.view.store.getGroups();
146 me.summaryData = me.generateSummaryData();
152 * Gets the data for printing a template row
154 * @param {Number} index The index in the template
155 * @return {Array} The template values
157 getPrintData: function(index){
159 columns = me.view.headerCt.getColumnsForTpl(),
161 length = columns.length,
163 name = me.summaryGroups[index - 1].name,
164 active = me.summaryData[name],
167 for (; i < length; ++i) {
169 column.gridSummaryValue = this.getColumnValue(column, active);
176 * Generates all of the summary data to be used when processing the template
178 * @return {Object} The summary data
180 generateSummaryData: function(){
184 store = me.view.store,
185 groupField = this.getGroupField(),
186 reader = store.proxy.reader,
187 groups = me.summaryGroups,
188 columns = me.view.headerCt.getColumnsForTpl(),
197 for (i = 0, length = groups.length; i < length; ++i) {
198 data[groups[i].name] = {};
202 * @cfg {String} [remoteRoot=undefined] The name of the property which contains the Array of
203 * summary objects. 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 && data[key] !== undefined) {
232 data[key][comp.id] = remote;