provide installation instructions
[extjs.git] / air / samples / tasks / js / DateTimeField.js
1 /*\r
2  * Ext JS Library 0.30\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 Ext.namespace('Ext.ux.form');\r
10 \r
11 /**\r
12   * Ext.ux.form.DateTime Extension Class for Ext 2.x Library\r
13   *\r
14   * @author    Ing. Jozef Sakalos\r
15   * @copyright (c) 2008, Ing. Jozef Sakalos\r
16   * @version $Id: Ext.ux.form.DateTime.js 645 2008-01-27 21:53:01Z jozo $\r
17   *\r
18   * @class Ext.ux.form.DateTime\r
19   * @extends Ext.form.Field\r
20   * \r
21   * @history\r
22   * 2008-1-31 Jack Slocum\r
23   * Updated for reformatting and code edits\r
24   */\r
25 Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {\r
26         defaultAutoCreate: {\r
27                 tag: 'input',\r
28                 type: 'hidden'\r
29         },\r
30         dateWidth: 135,\r
31         timeWidth: 100,\r
32         dtSeparator: ' ',\r
33         hiddenFormat: 'Y-m-d H:i:s',\r
34         otherToNow: true,\r
35         timePosition: 'right',\r
36         \r
37         initComponent: function(){\r
38                 // call parent initComponent\r
39                 Ext.ux.form.DateTime.superclass.initComponent.call(this);\r
40                 \r
41                 // create DateField\r
42                 var dateConfig = Ext.apply({}, {\r
43                         id: this.id + '-date',\r
44                         format: this.dateFormat,\r
45                         width: this.dateWidth,\r
46                         listeners: {\r
47                                 blur: {\r
48                                         scope: this,\r
49                                         fn: this.onBlur\r
50                                 },\r
51                                 focus: {\r
52                                         scope: this,\r
53                                         fn: this.onFocus\r
54                                 }\r
55                         }\r
56                 }, this.dateConfig);\r
57                 this.df = new Ext.form.DateField(dateConfig);\r
58                 delete (this.dateFormat);\r
59                 \r
60                 // create TimeField\r
61                 var timeConfig = Ext.apply({}, {\r
62                         id: this.id + '-time',\r
63                         format: this.timeFormat,\r
64                         width: this.timeWidth,\r
65                         listeners: {\r
66                                 blur: {\r
67                                         scope: this,\r
68                                         fn: this.onBlur\r
69                                 },\r
70                                 focus: {\r
71                                         scope: this,\r
72                                         fn: this.onFocus\r
73                                 }\r
74                         }\r
75                 }, this.timeConfig);\r
76                 this.tf = new Ext.form.TimeField(timeConfig);\r
77                 delete (this.timeFormat);\r
78                 \r
79                 // relay events\r
80                 this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);\r
81                 this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);\r
82                 \r
83         },\r
84         onRender: function(ct, position){\r
85                 if (this.isRendered) {\r
86                         return;\r
87                 }\r
88                 \r
89                 // render underlying field\r
90                 Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);\r
91                 \r
92                 // render DateField and TimeField\r
93                 // create bounding table\r
94                 if ('below' === this.timePosition) {\r
95                         var t = Ext.DomHelper.append(ct, {\r
96                                 tag: 'table',\r
97                                 style: 'border-collapse:collapse',\r
98                                 children: [{\r
99                                         tag: 'tr',\r
100                                         children: [{\r
101                                                 tag: 'td',\r
102                                                 style: 'padding-bottom:1px',\r
103                                                 cls: 'ux-datetime-date'\r
104                                         }]\r
105                                 }, {\r
106                                         tag: 'tr',\r
107                                         children: [{\r
108                                                 tag: 'td',\r
109                                                 cls: 'ux-datetime-time'\r
110                                         }]\r
111                                 }]\r
112                         }, true);\r
113                 }\r
114                 else {\r
115                         var t = Ext.DomHelper.append(ct, {\r
116                                 tag: 'table',\r
117                                 style: 'border-collapse:collapse',\r
118                                 children: [{\r
119                                         tag: 'tr',\r
120                                         children: [{\r
121                                                 tag: 'td',\r
122                                                 style: 'padding-right:4px',\r
123                                                 cls: 'ux-datetime-date'\r
124                                         }, {\r
125                                                 tag: 'td',\r
126                                                 cls: 'ux-datetime-time'\r
127                                         }]\r
128                                 }]\r
129                         }, true);\r
130                 }\r
131                 \r
132                 this.tableEl = t;\r
133                 this.wrap = t.wrap({\r
134                         cls: 'x-form-field-wrap'\r
135                 });\r
136                 this.wrap.on("mousedown", this.onMouseDown, this, {\r
137                         delay: 10\r
138                 });\r
139                 \r
140                 // render DateField & TimeField\r
141                 this.df.render(t.child('td.ux-datetime-date'));\r
142                 this.tf.render(t.child('td.ux-datetime-time'));\r
143                 \r
144                 if (Ext.isIE && Ext.isStrict) {\r
145                         t.select('input').applyStyles({\r
146                                 top: 0\r
147                         });\r
148                 }\r
149                 \r
150                 this.on('specialkey', this.onSpecialKey, this);\r
151                 \r
152                 this.df.el.swallowEvent(['keydown', 'keypress']);\r
153                 this.tf.el.swallowEvent(['keydown', 'keypress']);\r
154                 \r
155                 // create errorIcon for side invalid\r
156                 if ('side' === this.msgTarget) {\r
157                         var elp = this.el.findParent('.x-form-element', 10, true);\r
158                         this.errorIcon = elp.createChild({\r
159                                 cls: 'x-form-invalid-icon'\r
160                         });\r
161                         \r
162                         this.df.errorIcon = this.errorIcon;\r
163                         this.tf.errorIcon = this.errorIcon;\r
164                 }\r
165                 \r
166                 this.isRendered = true;\r
167                 \r
168         },\r
169         getPositionEl: function(){\r
170                 return this.wrap;\r
171         },\r
172         getResizeEl: function(){\r
173                 return this.wrap;\r
174         },\r
175         \r
176         adjustSize: Ext.BoxComponent.prototype.adjustSize,\r
177         \r
178         alignErrorIcon: function(){\r
179                 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);\r
180         },\r
181         \r
182         onSpecialKey: function(t, e){\r
183                 if (e.getKey() == e.TAB) {\r
184                         if (t === this.df && !e.shiftKey) {\r
185                                 e.stopEvent();\r
186                                 this.tf.focus();\r
187                         }\r
188                         if (t === this.tf && e.shiftKey) {\r
189                                 e.stopEvent();\r
190                                 this.df.focus();\r
191                         }\r
192                 }\r
193         },\r
194         \r
195         setSize: function(w, h){\r
196                 if (!w) {\r
197                         return;\r
198                 }\r
199                 if ('below' == this.timePosition) {\r
200                         this.df.setSize(w, h);\r
201                         this.tf.setSize(w, h)\r
202                         if (Ext.isIE) {\r
203                                 this.df.el.up('td').setWidth(w);\r
204                                 this.tf.el.up('td').setWidth(w);\r
205                         }\r
206                 }\r
207                 else {\r
208                         this.df.setSize(w - this.timeWidth - 4, h);\r
209                         this.tf.setSize(this.timeWidth, h);\r
210                         \r
211                         if (Ext.isIE) {\r
212                                 this.df.el.up('td').setWidth(w - this.timeWidth - 4);\r
213                                 this.tf.el.up('td').setWidth(this.timeWidth);\r
214                         }\r
215                 }\r
216                 \r
217         },\r
218         \r
219         setValue: function(val){\r
220                 if (!val) {\r
221                         this.setDate('');\r
222                         this.setTime('');\r
223                         this.updateValue();\r
224                         return;\r
225                 }\r
226                 // clear cross frame AIR nonsense\r
227                 val = new Date(val.getTime());\r
228                 var da, time;\r
229                 if (Ext.isDate(val)) {\r
230                         this.setDate(val);\r
231                         this.setTime(val);\r
232                         this.dateValue = new Date(val);\r
233                 }\r
234                 else {\r
235                         da = val.split(this.dtSeparator);\r
236                         this.setDate(da[0]);\r
237                         if (da[1]) {\r
238                                 this.setTime(da[1]);\r
239                         }\r
240                 }\r
241                 this.updateValue();\r
242         },\r
243         \r
244         getValue: function(){\r
245                 // create new instance of date\r
246                 return this.dateValue ? new Date(this.dateValue) : '';\r
247         },\r
248         \r
249         onMouseDown: function(e){\r
250                 // just to prevent blur event when clicked in the middle of fields\r
251                 this.wrapClick = 'td' === e.target.nodeName.toLowerCase();\r
252         },\r
253         \r
254         onFocus: function(){\r
255                 if (!this.hasFocus) {\r
256                         this.hasFocus = true;\r
257                         this.startValue = this.getValue();\r
258                         this.fireEvent("focus", this);\r
259                 }\r
260         },\r
261         \r
262         onBlur: function(f){\r
263                 // called by both DateField and TimeField blur events\r
264                 \r
265                 // revert focus to previous field if clicked in between\r
266                 if (this.wrapClick) {\r
267                         f.focus();\r
268                         this.wrapClick = false;\r
269                 }\r
270                 \r
271                 // update underlying value\r
272                 if (f === this.df) {\r
273                         this.updateDate();\r
274                 }\r
275                 else {\r
276                         this.updateTime();\r
277                 }\r
278                 this.updateHidden();\r
279                 \r
280                 // fire events later\r
281                 (function(){\r
282                         if (!this.df.hasFocus && !this.tf.hasFocus) {\r
283                                 var v = this.getValue();\r
284                                 if (String(v) !== String(this.startValue)) {\r
285                                         this.fireEvent("change", this, v, this.startValue);\r
286                                 }\r
287                                 this.hasFocus = false;\r
288                                 this.fireEvent('blur', this);\r
289                         }\r
290                 }).defer(100, this);\r
291                 \r
292         },\r
293         updateDate: function(){\r
294         \r
295                 var d = this.df.getValue();\r
296                 if (d) {\r
297                         if (!Ext.isDate(this.dateValue)) {\r
298                                 this.initDateValue();\r
299                                 if (!this.tf.getValue()) {\r
300                                         this.setTime(this.dateValue);\r
301                                 }\r
302                         }\r
303                         this.dateValue.setFullYear(d.getFullYear());\r
304                         this.dateValue.setMonth(d.getMonth());\r
305                         this.dateValue.setDate(d.getDate());\r
306                 }\r
307                 else {\r
308                         this.dateValue = '';\r
309                         this.setTime('');\r
310                 }\r
311         },\r
312         updateTime: function(){\r
313                 var t = this.tf.getValue();\r
314                 if (t && !Ext.isDate(t)) {\r
315                         t = Date.parseDate(t, this.tf.format);\r
316                 }\r
317                 if (t && !this.df.getValue()) {\r
318                         this.initDateValue();\r
319                         this.setDate(this.dateValue);\r
320                 }\r
321                 if (Ext.isDate(this.dateValue)) {\r
322                         if (t) {\r
323                                 this.dateValue.setHours(t.getHours());\r
324                                 this.dateValue.setMinutes(t.getMinutes());\r
325                                 this.dateValue.setSeconds(t.getSeconds());\r
326                         }\r
327                         else {\r
328                                 this.dateValue.setHours(0);\r
329                                 this.dateValue.setMinutes(0);\r
330                                 this.dateValue.setSeconds(0);\r
331                         }\r
332                 }\r
333         },\r
334         initDateValue: function(){\r
335                 this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);\r
336         },\r
337         updateHidden: function(){\r
338                 if (this.isRendered) {\r
339                         var value = Ext.isDate(this.dateValue) ? this.dateValue.format(this.hiddenFormat) : '';\r
340                         this.el.dom.value = value;\r
341                 }\r
342         },\r
343         updateValue: function(){\r
344         \r
345                 this.updateDate();\r
346                 this.updateTime();\r
347                 this.updateHidden();\r
348                 \r
349                 return;\r
350                 \r
351         },\r
352         setDate: function(date){\r
353                 this.df.setValue(date);\r
354         },\r
355         setTime: function(date){\r
356                 this.tf.setValue(date);\r
357         },\r
358         isValid: function(){\r
359                 return this.df.isValid() && this.tf.isValid();\r
360         },\r
361         validate: function(){\r
362                 return this.df.validate() && this.tf.validate();\r
363         },\r
364         focus: function(){\r
365                 this.df.focus();\r
366         },\r
367         \r
368         onDisable : function(){\r
369                 if(this.rendered){\r
370                         this.df.disable();\r
371                         this.tf.disable();\r
372                 }\r
373         },\r
374         \r
375         onEnable : function(){\r
376                 if(this.rendered){\r
377                         this.df.enable();\r
378                         this.tf.enable();\r
379                 }\r
380         }\r
381 });\r
382 \r
383 // register xtype\r
384 Ext.reg('xdatetime', Ext.ux.form.DateTime);