4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-form-field-Time'>/**
19 </span> * Provides a time input field with a time dropdown and automatic time validation.
21 * This field recognizes and uses JavaScript Date objects as its main {@link #value} type (only the time portion of the
22 * date is used; the month/day/year are ignored). In addition, it recognizes string values which are parsed according to
23 * the {@link #format} and/or {@link #altFormats} configs. These may be reconfigured to use time formats appropriate for
26 * The field may be limited to a certain range of times by using the {@link #minValue} and {@link #maxValue} configs,
27 * and the interval between time options in the dropdown can be changed with the {@link #increment} config.
32 * Ext.create('Ext.form.Panel', {
36 * renderTo: Ext.getBody(),
40 * fieldLabel: 'Time In',
41 * minValue: '6:00 AM',
42 * maxValue: '8:00 PM',
48 * fieldLabel: 'Time Out',
49 * minValue: '6:00 AM',
50 * maxValue: '8:00 PM',
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'],
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 {@link #triggerBaseCls}
65 * by default and triggerCls will be **appended** if specified. Defaults to 'x-form-time-trigger' for the Time field
68 triggerCls: Ext.baseCSSPrefix + 'form-time-trigger',
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 time in a
73 * valid format -- see {@link #format} and {@link #altFormats}.
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 time in a
79 * valid format -- see {@link #format} and {@link #altFormats}.
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}.
86 minText : "The time in this field must be equal to or after {0}",
88 <span id='Ext-form-field-Time-cfg-maxText'> /**
89 </span> * @cfg {String} maxText
90 * The error text to display when the entered time is after {@link #maxValue}.
92 maxText : "The time in this field must be equal to or before {0}",
94 <span id='Ext-form-field-Time-cfg-invalidText'> /**
95 </span> * @cfg {String} invalidText
96 * The error text to display when the time in the field is invalid.
98 invalidText : "{0} is not a valid time",
100 <span id='Ext-form-field-Time-cfg-format'> /**
101 </span> * @cfg {String} format
102 * The default time format string which can be overriden for localization support. The format must be valid
103 * according to {@link Ext.Date#parse} (defaults to 'g:i A', e.g., '3:15 PM'). For 24-hour time format try 'H:i'
106 format : "g:i A",
108 <span id='Ext-form-field-Time-cfg-submitFormat'> /**
109 </span> * @cfg {String} submitFormat
110 * The date format string which will be submitted to the server. The format must be valid according to {@link
111 * Ext.Date#parse} (defaults to {@link #format}).
114 <span id='Ext-form-field-Time-cfg-altFormats'> /**
115 </span> * @cfg {String} altFormats
116 * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
119 altFormats : "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",
121 <span id='Ext-form-field-Time-cfg-increment'> /**
122 </span> * @cfg {Number} increment
123 * The number of minutes between each time value in the list.
127 <span id='Ext-form-field-Time-cfg-pickerMaxHeight'> /**
128 </span> * @cfg {Number} pickerMaxHeight
129 * The maximum height of the {@link Ext.picker.Time} dropdown.
131 pickerMaxHeight: 300,
133 <span id='Ext-form-field-Time-cfg-selectOnTab'> /**
134 </span> * @cfg {Boolean} selectOnTab
135 * Whether the Tab key should select the currently highlighted item.
139 <span id='Ext-form-field-Time-property-initDate'> /**
141 * This is the date to use when generating time values in the absence of either minValue
142 * or maxValue. Using the current date causes DST issues on DST boundary dates, so this is an
143 * arbitrary "safe" date that can be any date aside from DST boundary dates.
145 initDate: '1/1/2008',
146 initDateFormat: 'j/n/Y',
149 initComponent: function() {
162 initValue: function() {
166 // If a String value was supplied, try to convert it to a proper Date object
167 if (Ext.isString(value)) {
168 me.value = me.rawToValue(value);
174 <span id='Ext-form-field-Time-method-setMinValue'> /**
175 </span> * Replaces any existing {@link #minValue} with the new time and refreshes the picker's range.
176 * @param {Date/String} value The minimum time that can be selected
178 setMinValue: function(value) {
181 me.setLimit(value, true);
183 picker.setMinValue(me.minValue);
187 <span id='Ext-form-field-Time-method-setMaxValue'> /**
188 </span> * Replaces any existing {@link #maxValue} with the new time and refreshes the picker's range.
189 * @param {Date/String} value The maximum time that can be selected
191 setMaxValue: function(value) {
194 me.setLimit(value, false);
196 picker.setMaxValue(me.maxValue);
200 <span id='Ext-form-field-Time-method-setLimit'> /**
202 * Updates either the min or max value. Converts the user's value into a Date object whose
203 * year/month/day is set to the {@link #initDate} so that only the time fields are significant.
205 setLimit: function(value, isMin) {
208 if (Ext.isString(value)) {
209 d = me.parseDate(value);
211 else if (Ext.isDate(value)) {
215 val = Ext.Date.clearTime(new Date(me.initDate));
216 val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
217 me[isMin ? 'minValue' : 'maxValue'] = val;
221 rawToValue: function(rawValue) {
222 return this.parseDate(rawValue) || rawValue || null;
225 valueToRaw: function(value) {
226 return this.formatDate(this.parseDate(value));
229 <span id='Ext-form-field-Time-method-getErrors'> /**
230 </span> * Runs all of Time's validations and returns an array of any errors. Note that this first runs Text's validations,
231 * so the returned array is an amalgamation of all field errors. The additional validation checks are testing that
232 * the time format is valid, that the chosen time is within the {@link #minValue} and {@link #maxValue} constraints
234 * @param {Object} [value] The value to get errors for (defaults to the current field value)
235 * @return {String[]} All validation errors for this field
237 getErrors: function(value) {
239 format = Ext.String.format,
240 errors = me.callParent(arguments),
241 minValue = me.minValue,
242 maxValue = me.maxValue,
245 value = me.formatDate(value || me.processRawValue(me.getRawValue()));
247 if (value === null || value.length < 1) { // if it's blank and textfield didn't flag it then it's valid
251 date = me.parseDate(value);
253 errors.push(format(me.invalidText, value, me.format));
257 if (minValue && date < minValue) {
258 errors.push(format(me.minText, me.formatDate(minValue)));
261 if (maxValue && date > maxValue) {
262 errors.push(format(me.maxText, me.formatDate(maxValue)));
268 formatDate: function() {
269 return Ext.form.field.Date.prototype.formatDate.apply(this, arguments);
272 <span id='Ext-form-field-Time-method-parseDate'> /**
274 * Parses an input value into a valid Date object.
275 * @param {String/Date} value
277 parseDate: function(value) {
278 if (!value || Ext.isDate(value)) {
283 val = me.safeParse(value, me.format),
284 altFormats = me.altFormats,
285 altFormatsArray = me.altFormatsArray,
289 if (!val && altFormats) {
290 altFormatsArray = altFormatsArray || altFormats.split('|');
291 len = altFormatsArray.length;
292 for (; i < len && !val; ++i) {
293 val = me.safeParse(value, altFormatsArray[i]);
299 safeParse: function(value, format){
305 if (utilDate.formatContainsDateInfo(format)) {
306 // assume we've been given a full date
307 result = utilDate.parse(value, format);
309 // Use our initial safe date
310 parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format);
319 getSubmitValue: function() {
321 format = me.submitFormat || me.format,
322 value = me.getValue();
324 return value ? Ext.Date.format(value, format) : null;
327 <span id='Ext-form-field-Time-method-createPicker'> /**
329 * Creates the {@link Ext.picker.Time}
331 createPicker: function() {
333 picker = Ext.create('Ext.picker.Time', {
340 minValue: me.minValue,
341 maxValue: me.maxValue,
342 increment: me.increment,
344 ownerCt: this.ownerCt,
345 renderTo: document.body,
346 maxHeight: me.pickerMaxHeight,
347 focusOnToFront: false
350 me.mon(picker.getSelectionModel(), {
351 selectionchange: me.onListSelect,
358 <span id='Ext-form-field-Time-method-onExpand'> /**
360 * Enables the key nav for the Time picker when it is expanded.
361 * TODO this is largely the same logic as ComboBox, should factor out.
363 onExpand: function() {
365 keyNav = me.pickerKeyNav,
366 selectOnTab = me.selectOnTab,
367 picker = me.getPicker(),
368 lastSelected = picker.getSelectionModel().lastSelected,
372 keyNav = me.pickerKeyNav = Ext.create('Ext.view.BoundListKeyNav', this.inputEl, {
377 if(me.picker.highlightedItem) {
378 this.selectHighlighted(e);
384 // Tab key event is allowed to propagate to field
388 // stop tab monitoring from Ext.form.field.Trigger so it doesn't short-circuit selectOnTab
390 me.ignoreMonitorTab = true;
393 Ext.defer(keyNav.enable, 1, keyNav); //wait a bit so it doesn't react to the down arrow opening the picker
395 // Highlight the last selected item and scroll it into view
397 itemNode = picker.getNode(lastSelected);
399 picker.highlightItem(itemNode);
400 picker.el.scrollChildIntoView(itemNode, false);
405 <span id='Ext-form-field-Time-method-onCollapse'> /**
407 * Disables the key nav for the Time picker when it is collapsed.
409 onCollapse: function() {
411 keyNav = me.pickerKeyNav;
414 me.ignoreMonitorTab = false;
418 <span id='Ext-form-field-Time-method-onChange'> /**
420 * Clears the highlighted item in the picker on change.
421 * This prevents the highlighted item from being selected instead of the custom typed in value when the tab key is pressed.
423 onChange: function() {
427 me.callParent(arguments);
429 picker.clearHighlight();
433 <span id='Ext-form-field-Time-method-onListSelect'> /**
435 * Handles a time being selected from the Time picker.
437 onListSelect: function(list, recordArray) {
439 record = recordArray[0],
440 val = record ? record.get('date') : null;
442 me.fireEvent('select', me, val);
443 me.picker.clearHighlight();