Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / GroupingSummary.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-grid-feature-GroupingSummary'>/**
19 </span> * @class Ext.grid.feature.GroupingSummary
20  * @extends Ext.grid.feature.Grouping
21  * 
22  * This feature adds an aggregate summary row at the bottom of each group that is provided
23  * by the {@link Ext.grid.feature.Grouping} feature. There are 2 aspects to the summary:
24  * 
25  * ## Calculation
26  * 
27  * The summary value needs to be calculated for each column in the grid. This is controlled
28  * by the summaryType option specified on the column. There are several built in summary types,
29  * which can be specified as a string on the column configuration. These call underlying methods
30  * on the store:
31  *
32  *  - {@link Ext.data.Store#count count}
33  *  - {@link Ext.data.Store#sum sum}
34  *  - {@link Ext.data.Store#min min}
35  *  - {@link Ext.data.Store#max max}
36  *  - {@link Ext.data.Store#average average}
37  *
38  * Alternatively, the summaryType can be a function definition. If this is the case,
39  * the function is called with an array of records to calculate the summary value.
40  * 
41  * ## Rendering
42  * 
43  * Similar to a column, the summary also supports a summaryRenderer function. This
44  * summaryRenderer is called before displaying a value. The function is optional, if
45  * not specified the default calculated value is shown. The summaryRenderer is called with:
46  *
47  *  - value {Object} - The calculated value.
48  *  - summaryData {Object} - Contains all raw summary values for the row.
49  *  - field {String} - The name of the field we are calculating
50  * 
51  * ## Example Usage
52  *
53  *     Ext.define('TestResult', {
54  *         extend: 'Ext.data.Model',
55  *         fields: ['student', 'subject', {
56  *             name: 'mark',
57  *             type: 'int'
58  *         }]
59  *     });
60  *     
61  *     Ext.create('Ext.grid.Panel', {
62  *         width: 200,
63  *         height: 240,
64  *         renderTo: document.body,
65  *         features: [{
66  *             groupHeaderTpl: 'Subject: {name}',
67  *             ftype: 'groupingsummary'
68  *         }],
69  *         store: {
70  *             model: 'TestResult',
71  *             groupField: 'subject',
72  *             data: [{
73  *                 student: 'Student 1',
74  *                 subject: 'Math',
75  *                 mark: 84
76  *             },{
77  *                 student: 'Student 1',
78  *                 subject: 'Science',
79  *                 mark: 72
80  *             },{
81  *                 student: 'Student 2',
82  *                 subject: 'Math',
83  *                 mark: 96
84  *             },{
85  *                 student: 'Student 2',
86  *                 subject: 'Science',
87  *                 mark: 68
88  *             }]
89  *         },
90  *         columns: [{
91  *             dataIndex: 'student',
92  *             text: 'Name',
93  *             summaryType: 'count',
94  *             summaryRenderer: function(value){
95  *                 return Ext.String.format('{0} student{1}', value, value !== 1 ? 's' : ''); 
96  *             }
97  *         }, {
98  *             dataIndex: 'mark',
99  *             text: 'Mark',
100  *             summaryType: 'average'
101  *         }]
102  *     });
103  */
104 Ext.define('Ext.grid.feature.GroupingSummary', {
105     
106     /* Begin Definitions */
107     
108     extend: 'Ext.grid.feature.Grouping',
109     
110     alias: 'feature.groupingsummary',
111     
112     mixins: {
113         summary: 'Ext.grid.feature.AbstractSummary'
114     },
115     
116     /* End Definitions */
117
118      
119 <span id='Ext-grid-feature-GroupingSummary-method-getFeatureTpl'>   /**
120 </span>    * Modifies the row template to include the summary row.
121     * @private
122     * @return {String} The modified template
123     */
124    getFeatureTpl: function() {
125         var tpl = this.callParent(arguments);
126             
127         if (this.showSummaryRow) {
128             // lop off the end &lt;/tpl&gt; so we can attach it
129             tpl = tpl.replace('&lt;/tpl&gt;', '');
130             tpl += '{[this.printSummaryRow(xindex)]}&lt;/tpl&gt;';
131         }
132         return tpl;
133     },
134     
135 <span id='Ext-grid-feature-GroupingSummary-method-getFragmentTpl'>    /**
136 </span>     * Gets any fragments needed for the template.
137      * @private
138      * @return {Object} The fragments
139      */
140     getFragmentTpl: function() {
141         var me = this,
142             fragments = me.callParent();
143             
144         Ext.apply(fragments, me.getSummaryFragments());
145         if (me.showSummaryRow) {
146             // this gets called before render, so we'll setup the data here.
147             me.summaryGroups = me.view.store.getGroups();
148             me.summaryData = me.generateSummaryData();
149         }
150         return fragments;
151     },
152     
153 <span id='Ext-grid-feature-GroupingSummary-method-getPrintData'>    /**
154 </span>     * Gets the data for printing a template row
155      * @private
156      * @param {Number} index The index in the template
157      * @return {Array} The template values
158      */
159     getPrintData: function(index){
160         var me = this,
161             columns = me.view.headerCt.getColumnsForTpl(),
162             i = 0,
163             length = columns.length,
164             data = [],
165             name = me.summaryGroups[index - 1].name,
166             active = me.summaryData[name],
167             column;
168             
169         for (; i &lt; length; ++i) {
170             column = columns[i];
171             column.gridSummaryValue = this.getColumnValue(column, active);
172             data.push(column);
173         }
174         return data;
175     },
176     
177 <span id='Ext-grid-feature-GroupingSummary-method-generateSummaryData'>    /**
178 </span>     * Generates all of the summary data to be used when processing the template
179      * @private
180      * @return {Object} The summary data
181      */
182     generateSummaryData: function(){
183         var me = this,
184             data = {},
185             remoteData = {},
186             store = me.view.store,
187             groupField = this.getGroupField(),
188             reader = store.proxy.reader,
189             groups = me.summaryGroups,
190             columns = me.view.headerCt.getColumnsForTpl(),
191             remote,
192             i,
193             length,
194             fieldData,
195             root,
196             key,
197             comp;
198             
199         for (i = 0, length = groups.length; i &lt; length; ++i) {
200             data[groups[i].name] = {};
201         }
202         
203 <span id='Ext-grid-feature-GroupingSummary-cfg-remoteRoot'>    /**
204 </span>     * @cfg {String} remoteRoot.  The name of the property
205      * which contains the Array of summary objects.  Defaults to &lt;tt&gt;undefined&lt;/tt&gt;.
206      * It allows to use server-side calculated summaries.
207      */
208         if (me.remoteRoot &amp;&amp; reader.rawData) {
209             // reset reader root and rebuild extractors to extract summaries data
210             root = reader.root;
211             reader.root = me.remoteRoot;
212             reader.buildExtractors(true);
213             Ext.Array.each(reader.getRoot(reader.rawData), function(value) {
214                  remoteData[value[groupField]] = value;
215             });
216             // restore initial reader configuration
217             reader.root = root;
218             reader.buildExtractors(true);
219         }
220         
221         for (i = 0, length = columns.length; i &lt; length; ++i) {
222             comp = Ext.getCmp(columns[i].id);
223             fieldData = me.getSummary(store, comp.summaryType, comp.dataIndex, true);
224             
225             for (key in fieldData) {
226                 if (fieldData.hasOwnProperty(key)) {
227                     data[key][comp.id] = fieldData[key];
228                 }
229             }
230             
231             for (key in remoteData) {
232                 if (remoteData.hasOwnProperty(key)) {
233                     remote = remoteData[key][comp.dataIndex];
234                     if (remote !== undefined) {
235                         data[key][comp.id] = remote;
236                     }
237                 }
238             }
239         }
240         return data;
241     }
242 });
243 </pre>
244 </body>
245 </html>