]> git.proxmox.com Git - extjs.git/blame - extjs/classic/classic/src/grid/filters/filter/Date.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / src / grid / filters / filter / Date.js
CommitLineData
6527f429
DM
1/**\r
2 * The date grid filter allows you to create a filter selection that limits results\r
3 * to values matching specific date constraints. The filter can be set programmatically or via \r
4 * user input with a configurable {@link Ext.picker.Date DatePicker menu} in the filter section \r
5 * of the column header.\r
6 * \r
7 * Example Date Filter Usage:\r
8 * \r
9 * @example \r
10 * var shows = Ext.create('Ext.data.Store', {\r
11 * fields: ['id','show', {\r
12 * name: 'airDate',\r
13 * type: 'date',\r
14 * dateFormat: 'Y-m-d'\r
15 * }],\r
16 * data: [\r
17 * {id: 0, show: 'Battlestar Galactica', airDate: '1978-09-17'},\r
18 * {id: 1, show: 'Doctor Who', airDate: '1963-11-23'},\r
19 * {id: 2, show: 'Farscape', airDate: '1999-03-19'},\r
20 * {id: 3, show: 'Firefly', airDate: '2002-12-20'},\r
21 * {id: 4, show: 'Star Trek', airDate: '1966-09-08'},\r
22 * {id: 5, show: 'Star Wars: Christmas Special', airDate: '1978-11-17'}\r
23 * ]\r
24 * });\r
25 * \r
26 * Ext.create('Ext.grid.Panel', {\r
27 * renderTo: Ext.getBody(),\r
28 * title: 'Sci-Fi Television',\r
29 * height: 250,\r
30 * width: 375,\r
31 * store: shows,\r
32 * plugins: 'gridfilters',\r
33 * columns: [{\r
34 * dataIndex: 'id',\r
35 * text: 'ID',\r
36 * width: 50\r
37 * },{\r
38 * dataIndex: 'show',\r
39 * text: 'Show',\r
40 * flex: 1 \r
41 * },{\r
42 * xtype: 'datecolumn',\r
43 * dataIndex: 'airDate',\r
44 * text: 'Original Air Date',\r
45 * width: 125,\r
46 * filter: {\r
47 * type: 'date',\r
48 * \r
49 * // optional picker config\r
50 * pickerDefaults: {\r
51 * // any DatePicker configs\r
52 * } \r
53 * }\r
54 * }]\r
55 * }); \r
56 */\r
57Ext.define('Ext.grid.filters.filter.Date', {\r
58 extend: 'Ext.grid.filters.filter.TriFilter',\r
59 alias: 'grid.filter.date',\r
60 uses: ['Ext.picker.Date', 'Ext.menu.DatePicker'],\r
61\r
62 type: 'date',\r
63\r
64 config: {\r
65 //<locale type="object">\r
66 /**\r
67 * @cfg {Object} [fields]\r
68 * Configures field items individually. These properties override those defined\r
69 * by `{@link #itemDefaults}`.\r
70 *\r
71 * Example usage:\r
72 * fields: {\r
73 * gt: { // override fieldCfg options\r
74 * width: 200\r
75 * }\r
76 * },\r
77 */\r
78 fields: {\r
79 lt: {text: 'Before'},\r
80 gt: {text: 'After'},\r
81 eq: {text: 'On'}\r
82 },\r
83 //</locale>\r
84\r
85 /**\r
86 * @cfg {Object} pickerDefaults\r
87 * Configuration options for the date picker associated with each field.\r
88 */\r
89 pickerDefaults: {\r
90 xtype: 'datepicker',\r
91 border: 0\r
92 },\r
93\r
94 updateBuffer: 0,\r
95\r
96 /**\r
97 * @cfg {String} dateFormat\r
98 * The date format to return when using getValue.\r
99 * Defaults to {@link Ext.Date#defaultFormat}.\r
100 */\r
101 dateFormat: undefined\r
102 },\r
103\r
104 itemDefaults: {\r
105 xtype: 'menucheckitem',\r
106 selectOnFocus: true,\r
107 width: 125,\r
108 menu: {\r
109 layout: 'auto',\r
110 plain: true\r
111 }\r
112 },\r
113\r
114 /**\r
115 * @cfg {Date} maxDate\r
116 * Allowable date as passed to the Ext.DatePicker\r
117 * Defaults to undefined.\r
118 */\r
119\r
120 /**\r
121 * @cfg {Date} minDate\r
122 * Allowable date as passed to the Ext.DatePicker\r
123 * Defaults to undefined.\r
124 */\r
125\r
126 applyDateFormat: function(dateFormat) {\r
127 return dateFormat || Ext.Date.defaultFormat;\r
128 },\r
129\r
130 /**\r
131 * @private\r
132 * Template method that is to initialize the filter and install required menu items.\r
133 */\r
134 createMenu: function (config) {\r
135 var me = this,\r
136 listeners = {\r
137 scope: me,\r
138 checkchange: me.onCheckChange\r
139 },\r
140 menuItems = me.menuItems,\r
141 fields, itemDefaults, pickerCfg, i, len,\r
142 key, item, cfg, field;\r
143\r
144 me.callParent(arguments);\r
145\r
146 itemDefaults = me.getItemDefaults();\r
147 fields = me.getFields();\r
148\r
149 pickerCfg = Ext.apply({\r
150 minDate: me.minDate,\r
151 maxDate: me.maxDate,\r
152 format: me.dateFormat,\r
153 listeners: {\r
154 scope: me,\r
155 select: me.onMenuSelect\r
156 }\r
157 }, me.getPickerDefaults());\r
158\r
159 me.fields = {};\r
160\r
161 for (i = 0, len = menuItems.length; i < len; i++) {\r
162 key = menuItems[i];\r
163 if (key !== '-') {\r
164 cfg = {\r
165 menu: {\r
166 xtype: 'datemenu',\r
167 hideOnClick: false,\r
168 pickerCfg: Ext.apply({\r
169 itemId: key\r
170 }, pickerCfg)\r
171 }\r
172 };\r
173\r
174 if (itemDefaults) {\r
175 Ext.merge(cfg, itemDefaults);\r
176 }\r
177\r
178 if (fields) {\r
179 Ext.merge(cfg, fields[key]);\r
180 }\r
181\r
182 item = me.menu.add(cfg);\r
183 // Date filter types need the field to be the datepicker in TriFilter.setValue().\r
184 field = me.fields[key] = item.down('datepicker');\r
185 field.filter = me.filter[key];\r
186 field.filterKey = key;\r
187\r
188 item.on(listeners);\r
189 } else {\r
190 me.menu.add(key);\r
191 }\r
192 }\r
193 },\r
194\r
195 /**\r
196 * Gets the menu picker associated with the passed field\r
197 * @param {String} item The field identifier ('lt', 'gt', 'eq')\r
198 * @return {Object} The menu picker\r
199 */\r
200 getPicker: function (item){\r
201 return this.fields[item];\r
202 },\r
203\r
204 /**\r
205 * @private\r
206 * Remove the filter from the store but don't update its value or the field UI.\r
207 */\r
208 onCheckChange: function (field, checked) {\r
209 // Only do something if unchecked. If checked, it doesn't mean anything at this point since the column's store filter won't have\r
210 // any value (i.e., if a user checked this from an unchecked state, the corresponding field won't have a value for its filter).\r
211 var filter = field.down('datepicker').filter,\r
212 v;\r
213\r
214 // Only proceed if unchecked AND there's a filter value (i.e., there's something to do!).\r
215 if (!checked && filter.getValue()) {\r
216 // Normally we just want to remove the filter from the store, not also to null out the filter value. But, we want to call setValue()\r
217 // which will take care of unchecking the top-level menu item if it's been determined that Date* doesn't have any filters.\r
218 v = {};\r
219 v[filter.getOperator()] = null;\r
220 this.setValue(v);\r
221 }\r
222 },\r
223\r
224 onFilterRemove: function (operator) {\r
225 var v = {};\r
226\r
227 v[operator] = null;\r
228 this.setValue(v);\r
229 this.fields[operator].up('menuitem').setChecked(false, /*suppressEvents*/ true);\r
230 },\r
231\r
232 onStateRestore: function(filter) {\r
233 filter.setSerializer(this.getSerializer());\r
234 filter.setConvert(this.convertDateOnly);\r
235 },\r
236\r
237 getFilterConfig: function(config, key) {\r
238 config = this.callParent([config, key]);\r
239 config.serializer = this.getSerializer();\r
240 config.convert = this.convertDateOnly;\r
241 return config;\r
242 },\r
243\r
244 convertDateOnly: function(v) {\r
245 var result = null;\r
246 if (v) {\r
247 result = Ext.Date.clearTime(v, true).getTime();\r
248 }\r
249 return result;\r
250 },\r
251\r
252 getSerializer: function() {\r
253 var me = this;\r
254 return function(data) {\r
255 var value = data.value;\r
256 if (value) {\r
257 data.value = Ext.Date.format(value, me.getDateFormat());\r
258 }\r
259 };\r
260 },\r
261\r
262 /**\r
263 * Handler for when the DatePicker for a field fires the 'select' event\r
264 * @param {Ext.picker.Date} picker\r
265 * @param {Object} date\r
266 */\r
267 onMenuSelect: function (picker, date) {\r
268 var me = this,\r
269 fields = me.fields,\r
270 filters = me.filter,\r
271 field = fields[picker.itemId],\r
272 gt = fields.gt,\r
273 lt = fields.lt,\r
274 eq = fields.eq,\r
275 v = {};\r
276\r
277 field.up('menuitem').setChecked(true, /*suppressEvents*/ true);\r
278\r
279 if (field === eq) {\r
280 lt.up('menuitem').setChecked(false, true);\r
281 gt.up('menuitem').setChecked(false, true);\r
282 } else {\r
283 eq.up('menuitem').setChecked(false, true);\r
284 if (field === gt && (+lt.value < +date)) {\r
285 lt.up('menuitem').setChecked(false, true);\r
286 // Null so filter will be removed from store, but only if it currently has a value.\r
287 // The Trifilter uses the number of removed filters as one of the determinants to determine\r
288 // whether the gridfilter should be active, so don't push a value in unless it's changed.\r
289 if (filters.lt.getValue() != null) {\r
290 v.lt = null;\r
291 }\r
292 } else if (field === lt && (+gt.value > +date)) {\r
293 gt.up('menuitem').setChecked(false, true);\r
294 // Null so filter will be removed from store, but only if it currently has a value.\r
295 // The Trifilter uses the number of removed filters as one of the determinants to determine\r
296 // whether the gridfilter should be active, so don't push a value in unless it's changed.\r
297 if (filters.gt.getValue() != null) {\r
298 v.gt = null;\r
299 }\r
300 }\r
301 }\r
302\r
303 v[field.filterKey] = date;\r
304 me.setValue(v);\r
305\r
306 picker.up('menu').hide();\r
307 }\r
308});\r
309\r