]> git.proxmox.com Git - extjs.git/blame - extjs/build/examples/classic/calendar/src/form/field/DateRange.js
add extjs 6.0.1 sources
[extjs.git] / extjs / build / examples / classic / calendar / src / form / field / DateRange.js
CommitLineData
6527f429
DM
1/**\r
2 * @class Ext.form.field.DateRange\r
3 * @extends Ext.form.Field\r
4 * <p>A combination field that includes start and end dates and times, as well as an optional all-day checkbox.</p>\r
5 * @constructor\r
6 * @param {Object} config The config object\r
7 */\r
8Ext.define('Ext.calendar.form.field.DateRange', {\r
9 extend: 'Ext.form.FieldContainer',\r
10 alias: 'widget.daterangefield',\r
11 \r
12 requires: [\r
13 'Ext.form.field.Date',\r
14 'Ext.form.field.Time',\r
15 'Ext.form.Label',\r
16 'Ext.form.field.Checkbox',\r
17 'Ext.layout.container.Column'\r
18 ],\r
19 \r
20 /**\r
21 * @cfg {String} toText\r
22 * The text to display in between the date/time fields (defaults to 'to')\r
23 */\r
24 toText: 'to',\r
25 /**\r
26 * @cfg {String} allDayText\r
27 * The text to display as the label for the all day checkbox (defaults to 'All day')\r
28 */\r
29 allDayText: 'All day',\r
30 /**\r
31 * @cfg {String/Boolean} singleLine\r
32 * `true` to render the fields all on one line, `false` to break the start date/time and end date/time\r
33 * into two stacked rows of fields to preserve horizontal space (defaults to `true`).\r
34 */\r
35 singleLine: true,\r
36 /**\r
37 * @cfg {String} dateFormat\r
38 * The date display format used by the date fields (defaults to 'n/j/Y') \r
39 */\r
40 dateFormat: 'n/j/Y',\r
41 /**\r
42 * @cfg {String} timeFormat\r
43 * The time display format used by the time fields. By default the DateRange uses the\r
44 * {@link Ext.Date.use24HourTime} setting and sets the format to 'g:i A' for 12-hour time (e.g., 1:30 PM) \r
45 * or 'G:i' for 24-hour time (e.g., 13:30). This can also be overridden by a static format string if desired.\r
46 */\r
47 timeFormat: Ext.Date.use24HourTime ? 'G:i' : 'g:i A',\r
48 \r
49 // private\r
50 fieldLayout: 'hbox',\r
51\r
52 defaults: {\r
53 margin: '0 5 0 0'\r
54 },\r
55\r
56 // private\r
57 initComponent: function() {\r
58 var me = this;\r
59 \r
60 me.addCls('ext-dt-range');\r
61 \r
62 if (me.singleLine) {\r
63 me.layout = me.fieldLayout;\r
64 me.items = me.getFieldConfigs();\r
65 }\r
66 else {\r
67 me.items = [{\r
68 xtype: 'container',\r
69 layout: me.fieldLayout,\r
70 items: [\r
71 me.getStartDateConfig(),\r
72 me.getStartTimeConfig(),\r
73 me.getDateSeparatorConfig()\r
74 ]\r
75 },{\r
76 xtype: 'container',\r
77 layout: me.fieldLayout,\r
78 items: [\r
79 me.getEndDateConfig(),\r
80 me.getEndTimeConfig(),\r
81 me.getAllDayConfig()\r
82 ]\r
83 }];\r
84 }\r
85 \r
86 me.callParent(arguments);\r
87 me.initRefs();\r
88 },\r
89 \r
90 initRefs: function() {\r
91 var me = this;\r
92 me.startDate = me.down('#' + me.id + '-start-date');\r
93 me.startTime = me.down('#' + me.id + '-start-time');\r
94 me.endTime = me.down('#' + me.id + '-end-time');\r
95 me.endDate = me.down('#' + me.id + '-end-date');\r
96 me.allDay = me.down('#' + me.id + '-allday');\r
97 me.toLabel = me.down('#' + me.id + '-to-label');\r
98\r
99 me.startDate.validateOnChange = me.endDate.validateOnChange = false;\r
100\r
101 me.startDate.isValid = me.endDate.isValid = function() {\r
102 var me = this,\r
103 valid = Ext.isDate(me.getValue());\r
104 if (!valid) {\r
105 me.focus();\r
106 }\r
107 return valid;\r
108 };\r
109 },\r
110\r
111 getFieldConfigs: function() {\r
112 var me = this;\r
113 return [\r
114 me.getStartDateConfig(),\r
115 me.getStartTimeConfig(),\r
116 me.getDateSeparatorConfig(),\r
117 me.getEndTimeConfig(),\r
118 me.getEndDateConfig(),\r
119 me.getAllDayConfig()\r
120 ];\r
121 },\r
122 \r
123 getStartDateConfig: function() {\r
124 return {\r
125 xtype: 'datefield',\r
126 itemId: this.id + '-start-date',\r
127 format: this.dateFormat,\r
128 width: 100,\r
129 listeners: {\r
130 'blur': {\r
131 fn: function(){\r
132 this.onFieldChange('date', 'start');\r
133 },\r
134 scope: this\r
135 }\r
136 }\r
137 };\r
138 },\r
139 \r
140 getStartTimeConfig: function() {\r
141 return {\r
142 xtype: 'timefield',\r
143 itemId: this.id + '-start-time',\r
144 hidden: this.showTimes === false,\r
145 labelWidth: 0,\r
146 hideLabel: true,\r
147 width: 90,\r
148 format: this.timeFormat,\r
149 listeners: {\r
150 'select': {\r
151 fn: function(){\r
152 this.onFieldChange('time', 'start');\r
153 },\r
154 scope: this\r
155 }\r
156 }\r
157 };\r
158 },\r
159 \r
160 getEndDateConfig: function() {\r
161 return {\r
162 xtype: 'datefield',\r
163 itemId: this.id + '-end-date',\r
164 format: this.dateFormat,\r
165 hideLabel: true,\r
166 width: 100,\r
167 listeners: {\r
168 'blur': {\r
169 fn: function(){\r
170 this.onFieldChange('date', 'end');\r
171 },\r
172 scope: this\r
173 }\r
174 }\r
175 };\r
176 },\r
177 \r
178 getEndTimeConfig: function() {\r
179 return {\r
180 xtype: 'timefield',\r
181 itemId: this.id + '-end-time',\r
182 hidden: this.showTimes === false,\r
183 labelWidth: 0,\r
184 hideLabel: true,\r
185 width: 90,\r
186 format: this.timeFormat,\r
187 listeners: {\r
188 'select': {\r
189 fn: function(){\r
190 this.onFieldChange('time', 'end');\r
191 },\r
192 scope: this\r
193 }\r
194 }\r
195 };\r
196 },\r
197\r
198 getDuration: function() {\r
199 var me = this,\r
200 start = me.getDT('start'),\r
201 end = me.getDT('end');\r
202\r
203 return end.getTime() - start.getTime();\r
204 },\r
205 \r
206 getAllDayConfig: function() {\r
207 return {\r
208 xtype: 'checkbox',\r
209 itemId: this.id + '-allday',\r
210 hidden: this.showTimes === false || this.showAllDay === false,\r
211 boxLabel: this.allDayText,\r
212 margin: '2 5 0 0',\r
213 handler: this.onAllDayChange,\r
214 scope: this\r
215 };\r
216 },\r
217 \r
218 onAllDayChange: function(chk, checked) {\r
219 Ext.suspendLayouts();\r
220 this.startTime.setDisabled(checked).setVisible(!checked);\r
221 this.endTime.setDisabled(checked).setVisible(!checked);\r
222 Ext.resumeLayouts(true);\r
223 },\r
224 \r
225 getDateSeparatorConfig: function() {\r
226 return {\r
227 xtype: 'label',\r
228 itemId: this.id + '-to-label',\r
229 text: this.toText,\r
230 margin: '4 5 0 0'\r
231 };\r
232 },\r
233 \r
234 isSingleLine: function() {\r
235 var me = this;\r
236 \r
237 if (me.calculatedSingleLine === undefined) {\r
238 if(me.singleLine == 'auto'){\r
239 var ownerCtEl = me.ownerCt.getEl(),\r
240 w = me.ownerCt.getWidth() - ownerCtEl.getPadding('lr'),\r
241 el = ownerCtEl.down('.x-panel-body');\r
242 \r
243 if(el){\r
244 w -= el.getPadding('lr');\r
245 }\r
246 \r
247 el = ownerCtEl.down('.x-form-item-label');\r
248 if(el){\r
249 w -= el.getWidth() - el.getPadding('lr');\r
250 }\r
251 me.calculatedSingleLine = w <= me.singleLineMinWidth ? false : true;\r
252 }\r
253 else {\r
254 me.calculatedSingleLine = me.singleLine !== undefined ? me.singleLine : true;\r
255 }\r
256 }\r
257 return me.calculatedSingleLine;\r
258 },\r
259\r
260 // private\r
261 onFieldChange: function(type, startend){\r
262 this.checkDates(type, startend);\r
263 this.fireEvent('change', this, this.getValue());\r
264 },\r
265 \r
266 // private\r
267 checkDates: function(type, startend){\r
268 var me = this,\r
269 startField = me.down('#' + me.id + '-start-' + type),\r
270 endField = me.down('#' + me.id + '-end-' + type),\r
271 startValue = me.getDT('start'),\r
272 endValue = me.getDT('end');\r
273\r
274 if (!startValue || !endValue) {\r
275 return;\r
276 }\r
277\r
278 if(startValue > endValue){\r
279 if(startend=='start'){\r
280 endField.setValue(startValue);\r
281 }else{\r
282 startField.setValue(endValue);\r
283 me.checkDates(type, 'start');\r
284 }\r
285 }\r
286 if(type=='date'){\r
287 me.checkDates('time', startend);\r
288 }\r
289 },\r
290 \r
291 /**\r
292 * Returns an array containing the following values in order:<div class="mdetail-params"><ul>\r
293 * <li><b><code>DateTime</code></b> : <div class="sub-desc">The start date/time</div></li>\r
294 * <li><b><code>DateTime</code></b> : <div class="sub-desc">The end date/time</div></li>\r
295 * <li><b><code>Boolean</code></b> : <div class="sub-desc">True if the dates are all-day, false \r
296 * if the time values should be used</div></li><ul></div>\r
297 * @return {Array} The array of return values\r
298 */\r
299 getValue: function(){\r
300 var eDate = Ext.calendar.util.Date,\r
301 start = this.getDT('start'),\r
302 end = this.getDT('end'),\r
303 allDay = this.allDay.getValue();\r
304 \r
305 if (Ext.isDate(start) && Ext.isDate(end) && start.getTime() !== end.getTime()) {\r
306 if (!allDay && eDate.isMidnight(start) && eDate.isMidnight(end)) {\r
307 // 12:00am -> 12:00am over n days, all day event\r
308 allDay = true;\r
309 end = eDate.add(end, {\r
310 days: -1\r
311 });\r
312 }\r
313 }\r
314 \r
315 return [\r
316 start, \r
317 end,\r
318 allDay\r
319 ];\r
320 },\r
321 \r
322 // private getValue helper\r
323 getDT: function(startend){\r
324 var time = this[startend+'Time'].getValue(),\r
325 dt = this[startend+'Date'].getValue();\r
326 \r
327 if(Ext.isDate(dt)){\r
328 dt = Ext.Date.format(dt, this[startend + 'Date'].format);\r
329 }\r
330 else{\r
331 return null;\r
332 }\r
333 if(time && time !== ''){\r
334 time = Ext.Date.format(time, this[startend+'Time'].format);\r
335 var val = Ext.Date.parseDate(dt + ' ' + time, this[startend+'Date'].format + ' ' + this[startend+'Time'].format);\r
336 return val;\r
337 //return Ext.Date.parseDate(dt+' '+time, this[startend+'Date'].format+' '+this[startend+'Time'].format);\r
338 }\r
339 return Ext.Date.parseDate(dt, this[startend+'Date'].format);\r
340 \r
341 },\r
342 \r
343 /**\r
344 * Sets the values to use in the date range.\r
345 * @param {Array/Date/Object} v The value(s) to set into the field. Valid types are as follows:<div class="mdetail-params"><ul>\r
346 * <li><b><code>Array</code></b> : <div class="sub-desc">An array containing, in order, a start date, end date and all-day flag.\r
347 * This array should exactly match the return type as specified by {@link #getValue}.</div></li>\r
348 * <li><b><code>DateTime</code></b> : <div class="sub-desc">A single Date object, which will be used for both the start and\r
349 * end dates in the range. The all-day flag will be defaulted to false.</div></li>\r
350 * <li><b><code>Object</code></b> : <div class="sub-desc">An object containing properties for StartDate, EndDate and IsAllDay\r
351 * as defined in {@link Ext.calendar.data.EventMappings}.</div></li><ul></div>\r
352 */\r
353 setValue: function(v){\r
354 if(!v) {\r
355 return;\r
356 }\r
357 if(Ext.isArray(v)){\r
358 this.setDT(v[0], 'start');\r
359 this.setDT(v[1], 'end');\r
360 this.allDay.setValue(!!v[2]);\r
361 }\r
362 else if(Ext.isDate(v)){\r
363 this.setDT(v, 'start');\r
364 this.setDT(v, 'end');\r
365 this.allDay.setValue(false);\r
366 }\r
367 else if(v[Ext.calendar.data.EventMappings.StartDate.name]){ //object\r
368 this.setDT(v[Ext.calendar.data.EventMappings.StartDate.name], 'start');\r
369 if(!this.setDT(v[Ext.calendar.data.EventMappings.EndDate.name], 'end')){\r
370 this.setDT(v[Ext.calendar.data.EventMappings.StartDate.name], 'end');\r
371 }\r
372 this.allDay.setValue(!!v[Ext.calendar.data.EventMappings.IsAllDay.name]);\r
373 }\r
374 },\r
375 \r
376 // private setValue helper\r
377 setDT: function(dt, startend){\r
378 if(dt && Ext.isDate(dt)){\r
379 this[startend + 'Date'].setValue(dt);\r
380 this[startend + 'Time'].setValue(Ext.Date.format(dt, this[startend + 'Time'].format));\r
381 return true;\r
382 }\r
383 },\r
384 \r
385 // inherited docs\r
386 isDirty: function(){\r
387 var dirty = false;\r
388 if(this.rendered && !this.disabled) {\r
389 this.items.each(function(item){\r
390 if (item.isDirty()) {\r
391 dirty = true;\r
392 return false;\r
393 }\r
394 });\r
395 }\r
396 return dirty;\r
397 },\r
398 \r
399 // private\r
400 onDisable : function(){\r
401 this.delegateFn('disable');\r
402 },\r
403 \r
404 // private\r
405 onEnable : function(){\r
406 this.delegateFn('enable');\r
407 },\r
408 \r
409 // inherited docs\r
410 reset : function(){\r
411 this.delegateFn('reset');\r
412 },\r
413 \r
414 // private\r
415 delegateFn : function(fn){\r
416 this.items.each(function(item){\r
417 if (item[fn]) {\r
418 item[fn]();\r
419 }\r
420 });\r
421 },\r
422 \r
423 // private\r
424 beforeDestroy: function(){\r
425 Ext.destroy(this.fieldCt);\r
426 this.callParent(arguments);\r
427 },\r
428 \r
429 /**\r
430 * @method getRawValue\r
431 * @hide\r
432 */\r
433 getRawValue : Ext.emptyFn,\r
434 /**\r
435 * @method setRawValue\r
436 * @hide\r
437 */\r
438 setRawValue : Ext.emptyFn\r
439});