Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Time2.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-form-field-Time'>/**
19 </span> * @class Ext.form.field.Time
20  * @extends Ext.form.field.Picker
21  * &lt;p&gt;Provides a time input field with a time dropdown and automatic time validation.&lt;/p&gt;
22  * &lt;p&gt;This field recognizes and uses JavaScript Date objects as its main {@link #value} type (only the time
23  * portion of the date is used; the month/day/year are ignored). In addition, it recognizes string values which
24  * are parsed according to the {@link #format} and/or {@link #altFormats} configs. These may be reconfigured
25  * to use time formats appropriate for the user's locale.&lt;/p&gt;
26  * &lt;p&gt;The field may be limited to a certain range of times by using the {@link #minValue} and {@link #maxValue}
27  * configs, and the interval between time options in the dropdown can be changed with the {@link #increment} config.&lt;/p&gt;
28  * {@img Ext.form.Time/Ext.form.Time.png Ext.form.Time component}
29  * &lt;p&gt;Example usage:&lt;/p&gt;
30  * &lt;pre&gt;&lt;code&gt;
31 Ext.create('Ext.form.Panel', {
32     title: 'Time Card',
33     width: 300,
34     bodyPadding: 10,
35     renderTo: Ext.getBody(),        
36     items: [{
37         xtype: 'timefield',
38         name: 'in',
39         fieldLabel: 'Time In',
40         minValue: '6:00 AM',
41         maxValue: '8:00 PM',
42         increment: 30,
43         anchor: '100%'
44     }, {
45         xtype: 'timefield',
46         name: 'out',
47         fieldLabel: 'Time Out',
48         minValue: '6:00 AM',
49         maxValue: '8:00 PM',
50         increment: 30,
51         anchor: '100%'
52    }]
53 });
54 &lt;/code&gt;&lt;/pre&gt;
55  */
56 Ext.define('Ext.form.field.Time', {
57     extend:'Ext.form.field.Picker',
58     alias: 'widget.timefield',
59     requires: ['Ext.form.field.Date', 'Ext.picker.Time', 'Ext.view.BoundListKeyNav', 'Ext.Date'],
60     alternateClassName: ['Ext.form.TimeField', 'Ext.form.Time'],
61
62 <span id='Ext-form-field-Time-cfg-triggerCls'>    /**
63 </span>     * @cfg {String} triggerCls
64      * An additional CSS class used to style the trigger button.  The trigger will always get the
65      * {@link #triggerBaseCls} by default and &lt;tt&gt;triggerCls&lt;/tt&gt; will be &lt;b&gt;appended&lt;/b&gt; if specified.
66      * Defaults to &lt;tt&gt;'x-form-time-trigger'&lt;/tt&gt; for the Time field trigger.
67      */
68     triggerCls: Ext.baseCSSPrefix + 'form-time-trigger',
69
70 <span id='Ext-form-field-Time-cfg-minValue'>    /**
71 </span>     * @cfg {Date/String} minValue
72      * The minimum allowed time. Can be either a Javascript date object with a valid time value or a string
73      * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
74      */
75
76 <span id='Ext-form-field-Time-cfg-maxValue'>    /**
77 </span>     * @cfg {Date/String} maxValue
78      * The maximum allowed time. Can be either a Javascript date object with a valid time value or a string
79      * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
80      */
81
82 <span id='Ext-form-field-Time-cfg-minText'>    /**
83 </span>     * @cfg {String} minText
84      * The error text to display when the entered time is before {@link #minValue} (defaults to
85      * 'The time in this field must be equal to or after {0}').
86      */
87     minText : &quot;The time in this field must be equal to or after {0}&quot;,
88
89 <span id='Ext-form-field-Time-cfg-maxText'>    /**
90 </span>     * @cfg {String} maxText
91      * The error text to display when the entered time is after {@link #maxValue} (defaults to
92      * 'The time in this field must be equal to or before {0}').
93      */
94     maxText : &quot;The time in this field must be equal to or before {0}&quot;,
95
96 <span id='Ext-form-field-Time-cfg-invalidText'>    /**
97 </span>     * @cfg {String} invalidText
98      * The error text to display when the time in the field is invalid (defaults to
99      * '{value} is not a valid time').
100      */
101     invalidText : &quot;{0} is not a valid time&quot;,
102
103 <span id='Ext-form-field-Time-cfg-format'>    /**
104 </span>     * @cfg {String} format
105      * The default time format string which can be overriden for localization support.  The format must be
106      * valid according to {@link Ext.Date#parse} (defaults to 'g:i A', e.g., '3:15 PM').  For 24-hour time
107      * format try 'H:i' instead.
108      */
109     format : &quot;g:i A&quot;,
110
111 <span id='Ext-form-field-Time-cfg-submitFormat'>    /**
112 </span>     * @cfg {String} submitFormat The date format string which will be submitted to the server.
113      * The format must be valid according to {@link Ext.Date#parse} (defaults to &lt;tt&gt;{@link #format}&lt;/tt&gt;).
114      */
115
116 <span id='Ext-form-field-Time-cfg-altFormats'>    /**
117 </span>     * @cfg {String} altFormats
118      * Multiple date formats separated by &quot;|&quot; to try when parsing a user input value and it doesn't match the defined
119      * format (defaults to 'g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A').
120      */
121     altFormats : &quot;g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A&quot;,
122
123 <span id='Ext-form-field-Time-cfg-increment'>    /**
124 </span>     * @cfg {Number} increment
125      * The number of minutes between each time value in the list (defaults to 15).
126      */
127     increment: 15,
128
129 <span id='Ext-form-field-Time-cfg-pickerMaxHeight'>    /**
130 </span>     * @cfg {Number} pickerMaxHeight
131      * The maximum height of the {@link Ext.picker.Time} dropdown. Defaults to 300.
132      */
133     pickerMaxHeight: 300,
134
135 <span id='Ext-form-field-Time-cfg-selectOnTab'>    /**
136 </span>     * @cfg {Boolean} selectOnTab
137      * Whether the Tab key should select the currently highlighted item. Defaults to &lt;tt&gt;true&lt;/tt&gt;.
138      */
139     selectOnTab: true,
140
141 <span id='Ext-form-field-Time-property-initDate'>    /**
142 </span>     * @private
143      * This is the date to use when generating time values in the absence of either minValue
144      * or maxValue.  Using the current date causes DST issues on DST boundary dates, so this is an
145      * arbitrary &quot;safe&quot; date that can be any date aside from DST boundary dates.
146      */
147     initDate: '1/1/2008',
148     initDateFormat: 'j/n/Y',
149
150
151     initComponent: function() {
152         var me = this,
153             min = me.minValue,
154             max = me.maxValue;
155         if (min) {
156             me.setMinValue(min);
157         }
158         if (max) {
159             me.setMaxValue(max);
160         }
161         this.callParent();
162     },
163
164     initValue: function() {
165         var me = this,
166             value = me.value;
167
168         // If a String value was supplied, try to convert it to a proper Date object
169         if (Ext.isString(value)) {
170             me.value = me.rawToValue(value);
171         }
172
173         me.callParent();
174     },
175
176 <span id='Ext-form-field-Time-method-setMinValue'>    /**
177 </span>     * Replaces any existing {@link #minValue} with the new time and refreshes the picker's range.
178      * @param {Date/String} value The minimum time that can be selected
179      */
180     setMinValue: function(value) {
181         var me = this,
182             picker = me.picker;
183         me.setLimit(value, true);
184         if (picker) {
185             picker.setMinValue(me.minValue);
186         }
187     },
188
189 <span id='Ext-form-field-Time-method-setMaxValue'>    /**
190 </span>     * Replaces any existing {@link #maxValue} with the new time and refreshes the picker's range.
191      * @param {Date/String} value The maximum time that can be selected
192      */
193     setMaxValue: function(value) {
194         var me = this,
195             picker = me.picker;
196         me.setLimit(value, false);
197         if (picker) {
198             picker.setMaxValue(me.maxValue);
199         }
200     },
201
202 <span id='Ext-form-field-Time-method-setLimit'>    /**
203 </span>     * @private
204      * Updates either the min or max value. Converts the user's value into a Date object whose
205      * year/month/day is set to the {@link #initDate} so that only the time fields are significant.
206      */
207     setLimit: function(value, isMin) {
208         var me = this,
209             d, val;
210         if (Ext.isString(value)) {
211             d = me.parseDate(value);
212         }
213         else if (Ext.isDate(value)) {
214             d = value;
215         }
216         if (d) {
217             val = Ext.Date.clearTime(new Date(me.initDate));
218             val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
219             me[isMin ? 'minValue' : 'maxValue'] = val;
220         }
221     },
222
223     rawToValue: function(rawValue) {
224         return this.parseDate(rawValue) || rawValue || null;
225     },
226
227     valueToRaw: function(value) {
228         return this.formatDate(this.parseDate(value));
229     },
230
231 <span id='Ext-form-field-Time-method-getErrors'>    /**
232 </span>     * Runs all of Time's validations and returns an array of any errors. Note that this first
233      * runs Text's validations, so the returned array is an amalgamation of all field errors.
234      * The additional validation checks are testing that the time format is valid, that the chosen
235      * time is within the {@link #minValue} and {@link #maxValue} constraints set.
236      * @param {Mixed} value The value to get errors for (defaults to the current field value)
237      * @return {Array} All validation errors for this field
238      */
239     getErrors: function(value) {
240         var me = this,
241             format = Ext.String.format,
242             errors = me.callParent(arguments),
243             minValue = me.minValue,
244             maxValue = me.maxValue,
245             date;
246
247         value = me.formatDate(value || me.processRawValue(me.getRawValue()));
248
249         if (value === null || value.length &lt; 1) { // if it's blank and textfield didn't flag it then it's valid
250              return errors;
251         }
252
253         date = me.parseDate(value);
254         if (!date) {
255             errors.push(format(me.invalidText, value, me.format));
256             return errors;
257         }
258
259         if (minValue &amp;&amp; date &lt; minValue) {
260             errors.push(format(me.minText, me.formatDate(minValue)));
261         }
262
263         if (maxValue &amp;&amp; date &gt; maxValue) {
264             errors.push(format(me.maxText, me.formatDate(maxValue)));
265         }
266
267         return errors;
268     },
269
270     formatDate: function() {
271         return Ext.form.field.Date.prototype.formatDate.apply(this, arguments);
272     },
273
274 <span id='Ext-form-field-Time-method-parseDate'>    /**
275 </span>     * @private
276      * Parses an input value into a valid Date object.
277      * @param {String/Date} value
278      */
279     parseDate: function(value) {
280         if (!value || Ext.isDate(value)) {
281             return value;
282         }
283
284         var me = this,
285             val = me.safeParse(value, me.format),
286             altFormats = me.altFormats,
287             altFormatsArray = me.altFormatsArray,
288             i = 0,
289             len;
290
291         if (!val &amp;&amp; altFormats) {
292             altFormatsArray = altFormatsArray || altFormats.split('|');
293             len = altFormatsArray.length;
294             for (; i &lt; len &amp;&amp; !val; ++i) {
295                 val = me.safeParse(value, altFormatsArray[i]);
296             }
297         }
298         return val;
299     },
300
301     safeParse: function(value, format){
302         var me = this,
303             utilDate = Ext.Date,
304             parsedDate,
305             result = null;
306
307         if (utilDate.formatContainsDateInfo(format)) {
308             // assume we've been given a full date
309             result = utilDate.parse(value, format);
310         } else {
311             // Use our initial safe date
312             parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format);
313             if (parsedDate) {
314                 result = parsedDate;
315             }
316         }
317         return result;
318     },
319
320     // @private
321     getSubmitValue: function() {
322         var me = this,
323             format = me.submitFormat || me.format,
324             value = me.getValue();
325
326         return value ? Ext.Date.format(value, format) : null;
327     },
328
329 <span id='Ext-form-field-Time-method-createPicker'>    /**
330 </span>     * @private
331      * Creates the {@link Ext.picker.Time}
332      */
333     createPicker: function() {
334         var me = this,
335             picker = Ext.create('Ext.picker.Time', {
336                 selModel: {
337                     mode: 'SINGLE'
338                 },
339                 floating: true,
340                 hidden: true,
341                 minValue: me.minValue,
342                 maxValue: me.maxValue,
343                 increment: me.increment,
344                 format: me.format,
345                 ownerCt: this.ownerCt,
346                 renderTo: document.body,
347                 maxHeight: me.pickerMaxHeight,
348                 focusOnToFront: false
349             });
350
351         me.mon(picker.getSelectionModel(), {
352             selectionchange: me.onListSelect,
353             scope: me
354         });
355
356         return picker;
357     },
358
359 <span id='Ext-form-field-Time-method-onExpand'>    /**
360 </span>     * @private
361      * Enables the key nav for the Time picker when it is expanded.
362      * TODO this is largely the same logic as ComboBox, should factor out.
363      */
364     onExpand: function() {
365         var me = this,
366             keyNav = me.pickerKeyNav,
367             selectOnTab = me.selectOnTab,
368             picker = me.getPicker(),
369             lastSelected = picker.getSelectionModel().lastSelected,
370             itemNode;
371
372         if (!keyNav) {
373             keyNav = me.pickerKeyNav = Ext.create('Ext.view.BoundListKeyNav', this.inputEl, {
374                 boundList: picker,
375                 forceKeyDown: true,
376                 tab: function(e) {
377                     if (selectOnTab) {
378                         if(me.picker.highlightedItem) {
379                             this.selectHighlighted(e);
380                         } else {
381                             me.collapse();
382                         }
383                         me.triggerBlur();
384                     }
385                     // Tab key event is allowed to propagate to field
386                     return true;
387                 }
388             });
389             // stop tab monitoring from Ext.form.field.Trigger so it doesn't short-circuit selectOnTab
390             if (selectOnTab) {
391                 me.ignoreMonitorTab = true;
392             }
393         }
394         Ext.defer(keyNav.enable, 1, keyNav); //wait a bit so it doesn't react to the down arrow opening the picker
395
396         // Highlight the last selected item and scroll it into view
397         if (lastSelected) {
398             itemNode = picker.getNode(lastSelected);
399             if (itemNode) {
400                 picker.highlightItem(itemNode);
401                 picker.el.scrollChildIntoView(itemNode, false);
402             }
403         }
404     },
405
406 <span id='Ext-form-field-Time-method-onCollapse'>    /**
407 </span>     * @private
408      * Disables the key nav for the Time picker when it is collapsed.
409      */
410     onCollapse: function() {
411         var me = this,
412             keyNav = me.pickerKeyNav;
413         if (keyNav) {
414             keyNav.disable();
415             me.ignoreMonitorTab = false;
416         }
417     },
418
419 <span id='Ext-form-field-Time-method-onChange'>    /**
420 </span>     * @private
421      * Clears the highlighted item in the picker on change.
422      * This prevents the highlighted item from being selected instead of the custom typed in value when the tab key is pressed.
423      */
424     onChange: function() {
425         var me = this,
426             picker = me.picker;
427
428         me.callParent(arguments);
429         if(picker) {
430             picker.clearHighlight();
431         }
432     },
433
434 <span id='Ext-form-field-Time-method-onListSelect'>    /**
435 </span>     * @private
436      * Handles a time being selected from the Time picker.
437      */
438     onListSelect: function(list, recordArray) {
439         var me = this,
440             record = recordArray[0],
441             val = record ? record.get('date') : null;
442         me.setValue(val);
443         me.fireEvent('select', me, val);
444         me.picker.clearHighlight();
445         me.collapse();
446         me.inputEl.focus();
447     }
448 });
449
450 </pre>
451 </body>
452 </html>