Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[extjs.git] / src / data / GroupingStore.js
1 /*!
2  * Ext JS Library 3.1.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.data.GroupingStore\r
9  * @extends Ext.data.Store\r
10  * A specialized store implementation that provides for grouping records by one of the available fields. This\r
11  * is usually used in conjunction with an {@link Ext.grid.GroupingView} to proved the data model for\r
12  * a grouped GridPanel.\r
13  * @constructor\r
14  * Creates a new GroupingStore.\r
15  * @param {Object} config A config object containing the objects needed for the Store to access data,\r
16  * and read the data into Records.\r
17  * @xtype groupingstore\r
18  */\r
19 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {\r
20     \r
21     //inherit docs\r
22     constructor: function(config){\r
23         Ext.data.GroupingStore.superclass.constructor.call(this, config);\r
24         this.applyGroupField();\r
25     },\r
26     \r
27     /**\r
28      * @cfg {String} groupField\r
29      * The field name by which to sort the store's data (defaults to '').\r
30      */\r
31     /**\r
32      * @cfg {Boolean} remoteGroup\r
33      * True if the grouping should apply on the server side, false if it is local only (defaults to false).  If the\r
34      * grouping is local, it can be applied immediately to the data.  If it is remote, then it will simply act as a\r
35      * helper, automatically sending the grouping field name as the 'groupBy' param with each XHR call.\r
36      */\r
37     remoteGroup : false,\r
38     /**\r
39      * @cfg {Boolean} groupOnSort\r
40      * True to sort the data on the grouping field when a grouping operation occurs, false to sort based on the\r
41      * existing sort info (defaults to false).\r
42      */\r
43     groupOnSort:false,\r
44 \r
45         groupDir : 'ASC',\r
46         \r
47     /**\r
48      * Clears any existing grouping and refreshes the data using the default sort.\r
49      */\r
50     clearGrouping : function(){\r
51         this.groupField = false;\r
52         if(this.remoteGroup){\r
53             if(this.baseParams){\r
54                 delete this.baseParams.groupBy;\r
55             }\r
56             var lo = this.lastOptions;\r
57             if(lo && lo.params){\r
58                 delete lo.params.groupBy;\r
59             }\r
60             this.reload();\r
61         }else{\r
62             this.applySort();\r
63             this.fireEvent('datachanged', this);\r
64         }\r
65     },\r
66 \r
67     /**\r
68      * Groups the data by the specified field.\r
69      * @param {String} field The field name by which to sort the store's data\r
70      * @param {Boolean} forceRegroup (optional) True to force the group to be refreshed even if the field passed\r
71      * in is the same as the current grouping field, false to skip grouping on the same field (defaults to false)\r
72      */\r
73     groupBy : function(field, forceRegroup, direction){\r
74                 direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;\r
75         if(this.groupField == field && this.groupDir == direction && !forceRegroup){\r
76             return; // already grouped by this field\r
77         }\r
78         this.groupField = field;\r
79                 this.groupDir = direction;\r
80         this.applyGroupField();\r
81         if(this.groupOnSort){\r
82             this.sort(field, direction);\r
83             return;\r
84         }\r
85         if(this.remoteGroup){\r
86             this.reload();\r
87         }else{\r
88             var si = this.sortInfo || {};\r
89             if(si.field != field || si.direction != direction){\r
90                 this.applySort();\r
91             }else{\r
92                 this.sortData(field, direction);\r
93             }\r
94             this.fireEvent('datachanged', this);\r
95         }\r
96     },\r
97     \r
98     // private\r
99     applyGroupField: function(){\r
100         if(this.remoteGroup){\r
101             if(!this.baseParams){\r
102                 this.baseParams = {};\r
103             }\r
104             this.baseParams.groupBy = this.groupField;\r
105             this.baseParams.groupDir = this.groupDir;\r
106         }\r
107     },\r
108 \r
109     // private\r
110     applySort : function(){\r
111         Ext.data.GroupingStore.superclass.applySort.call(this);\r
112         if(!this.groupOnSort && !this.remoteGroup){\r
113             var gs = this.getGroupState();\r
114             if(gs && (gs != this.sortInfo.field || this.groupDir != this.sortInfo.direction)){\r
115                 this.sortData(this.groupField, this.groupDir);\r
116             }\r
117         }\r
118     },\r
119 \r
120     // private\r
121     applyGrouping : function(alwaysFireChange){\r
122         if(this.groupField !== false){\r
123             this.groupBy(this.groupField, true, this.groupDir);\r
124             return true;\r
125         }else{\r
126             if(alwaysFireChange === true){\r
127                 this.fireEvent('datachanged', this);\r
128             }\r
129             return false;\r
130         }\r
131     },\r
132 \r
133     // private\r
134     getGroupState : function(){\r
135         return this.groupOnSort && this.groupField !== false ?\r
136                (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;\r
137     }\r
138 });\r
139 Ext.reg('groupingstore', Ext.data.GroupingStore);