<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</script>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-form-field-Time'>/**
-</span> * @class Ext.form.field.Time
- * @extends Ext.form.field.Picker
- * <p>Provides a time input field with a time dropdown and automatic time validation.</p>
- * <p>This field recognizes and uses JavaScript Date objects as its main {@link #value} type (only the time
- * portion of the date is used; the month/day/year are ignored). In addition, it recognizes string values which
- * are parsed according to the {@link #format} and/or {@link #altFormats} configs. These may be reconfigured
- * to use time formats appropriate for the user's locale.</p>
- * <p>The field may be limited to a certain range of times by using the {@link #minValue} and {@link #maxValue}
- * configs, and the interval between time options in the dropdown can be changed with the {@link #increment} config.</p>
- * {@img Ext.form.Time/Ext.form.Time.png Ext.form.Time component}
- * <p>Example usage:</p>
- * <pre><code>
-Ext.create('Ext.form.Panel', {
- title: 'Time Card',
- width: 300,
- bodyPadding: 10,
- renderTo: Ext.getBody(),
- items: [{
- xtype: 'timefield',
- name: 'in',
- fieldLabel: 'Time In',
- minValue: '6:00 AM',
- maxValue: '8:00 PM',
- increment: 30,
- anchor: '100%'
- }, {
- xtype: 'timefield',
- name: 'out',
- fieldLabel: 'Time Out',
- minValue: '6:00 AM',
- maxValue: '8:00 PM',
- increment: 30,
- anchor: '100%'
- }]
-});
-</code></pre>
+ <pre class="prettyprint lang-js"><span id='Ext-picker-Time'>/**
+</span> * A time picker which provides a list of times from which to choose. This is used by the Ext.form.field.Time
+ * class to allow browsing and selection of valid times, but could also be used with other components.
+ *
+ * By default, all times starting at midnight and incrementing every 15 minutes will be presented. This list of
+ * available times can be controlled using the {@link #minValue}, {@link #maxValue}, and {@link #increment}
+ * configuration properties. The format of the times presented in the list can be customized with the {@link #format}
+ * config.
+ *
+ * To handle when the user selects a time from the list, you can subscribe to the {@link #selectionchange} event.
+ *
+ * @example
+ * Ext.create('Ext.picker.Time', {
+ * width: 60,
+ * minValue: Ext.Date.parse('04:30:00 AM', 'h:i:s A'),
+ * maxValue: Ext.Date.parse('08:00:00 AM', 'h:i:s A'),
+ * renderTo: Ext.getBody()
+ * });
*/
-Ext.define('Ext.form.field.Time', {
- extend:'Ext.form.field.Picker',
- alias: 'widget.timefield',
- requires: ['Ext.form.field.Date', 'Ext.picker.Time', 'Ext.view.BoundListKeyNav', 'Ext.Date'],
- alternateClassName: ['Ext.form.TimeField', 'Ext.form.Time'],
-
-<span id='Ext-form-field-Time-cfg-triggerCls'> /**
-</span> * @cfg {String} triggerCls
- * An additional CSS class used to style the trigger button. The trigger will always get the
- * {@link #triggerBaseCls} by default and <tt>triggerCls</tt> will be <b>appended</b> if specified.
- * Defaults to <tt>'x-form-time-trigger'</tt> for the Time field trigger.
- */
- triggerCls: Ext.baseCSSPrefix + 'form-time-trigger',
-
-<span id='Ext-form-field-Time-cfg-minValue'> /**
-</span> * @cfg {Date/String} minValue
- * The minimum allowed time. Can be either a Javascript date object with a valid time value or a string
- * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
- */
-
-<span id='Ext-form-field-Time-cfg-maxValue'> /**
-</span> * @cfg {Date/String} maxValue
- * The maximum allowed time. Can be either a Javascript date object with a valid time value or a string
- * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
- */
+Ext.define('Ext.picker.Time', {
+ extend: 'Ext.view.BoundList',
+ alias: 'widget.timepicker',
+ requires: ['Ext.data.Store', 'Ext.Date'],
-<span id='Ext-form-field-Time-cfg-minText'> /**
-</span> * @cfg {String} minText
- * The error text to display when the entered time is before {@link #minValue} (defaults to
- * 'The time in this field must be equal to or after {0}').
+<span id='Ext-picker-Time-cfg-minValue'> /**
+</span> * @cfg {Date} minValue
+ * The minimum time to be shown in the list of times. This must be a Date object (only the time fields will be
+ * used); no parsing of String values will be done.
*/
- minText : "The time in this field must be equal to or after {0}",
-<span id='Ext-form-field-Time-cfg-maxText'> /**
-</span> * @cfg {String} maxText
- * The error text to display when the entered time is after {@link #maxValue} (defaults to
- * 'The time in this field must be equal to or before {0}').
+<span id='Ext-picker-Time-cfg-maxValue'> /**
+</span> * @cfg {Date} maxValue
+ * The maximum time to be shown in the list of times. This must be a Date object (only the time fields will be
+ * used); no parsing of String values will be done.
*/
- maxText : "The time in this field must be equal to or before {0}",
-<span id='Ext-form-field-Time-cfg-invalidText'> /**
-</span> * @cfg {String} invalidText
- * The error text to display when the time in the field is invalid (defaults to
- * '{value} is not a valid time').
+<span id='Ext-picker-Time-cfg-increment'> /**
+</span> * @cfg {Number} increment
+ * The number of minutes between each time value in the list.
*/
- invalidText : "{0} is not a valid time",
+ increment: 15,
-<span id='Ext-form-field-Time-cfg-format'> /**
+<span id='Ext-picker-Time-cfg-format'> /**
</span> * @cfg {String} format
- * The default time format string which can be overriden for localization support. The format must be
- * valid according to {@link Ext.Date#parse} (defaults to 'g:i A', e.g., '3:15 PM'). For 24-hour time
- * format try 'H:i' instead.
+ * The default time format string which can be overriden for localization support. The format must be valid
+ * according to {@link Ext.Date#parse} (defaults to 'g:i A', e.g., '3:15 PM'). For 24-hour time format try 'H:i'
+ * instead.
*/
format : "g:i A",
-<span id='Ext-form-field-Time-cfg-submitFormat'> /**
-</span> * @cfg {String} submitFormat The date format string which will be submitted to the server.
- * The format must be valid according to {@link Ext.Date#parse} (defaults to <tt>{@link #format}</tt>).
- */
-
-<span id='Ext-form-field-Time-cfg-altFormats'> /**
-</span> * @cfg {String} altFormats
- * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
- * 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').
+<span id='Ext-picker-Time-property-displayField'> /**
+</span> * @hide
+ * The field in the implicitly-generated Model objects that gets displayed in the list. This is
+ * an internal field name only and is not useful to change via config.
*/
- 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",
+ displayField: 'disp',
-<span id='Ext-form-field-Time-cfg-increment'> /**
-</span> * @cfg {Number} increment
- * The number of minutes between each time value in the list (defaults to 15).
- */
- increment: 15,
-
-<span id='Ext-form-field-Time-cfg-pickerMaxHeight'> /**
-</span> * @cfg {Number} pickerMaxHeight
- * The maximum height of the {@link Ext.picker.Time} dropdown. Defaults to 300.
+<span id='Ext-picker-Time-property-initDate'> /**
+</span> * @private
+ * Year, month, and day that all times will be normalized into internally.
*/
- pickerMaxHeight: 300,
+ initDate: [2008,0,1],
-<span id='Ext-form-field-Time-cfg-selectOnTab'> /**
-</span> * @cfg {Boolean} selectOnTab
- * Whether the Tab key should select the currently highlighted item. Defaults to <tt>true</tt>.
- */
- selectOnTab: true,
+ componentCls: Ext.baseCSSPrefix + 'timepicker',
-<span id='Ext-form-field-Time-property-initDate'> /**
-</span> * @private
- * This is the date to use when generating time values in the absence of either minValue
- * or maxValue. Using the current date causes DST issues on DST boundary dates, so this is an
- * arbitrary "safe" date that can be any date aside from DST boundary dates.
+<span id='Ext-picker-Time-property-loadMask'> /**
+</span> * @hide
*/
- initDate: '1/1/2008',
- initDateFormat: 'j/n/Y',
-
+ loadMask: false,
initComponent: function() {
var me = this,
- min = me.minValue,
- max = me.maxValue;
- if (min) {
- me.setMinValue(min);
- }
- if (max) {
- me.setMaxValue(max);
- }
- this.callParent();
- },
+ dateUtil = Ext.Date,
+ clearTime = dateUtil.clearTime,
+ initDate = me.initDate;
- initValue: function() {
- var me = this,
- value = me.value;
+ // Set up absolute min and max for the entire day
+ me.absMin = clearTime(new Date(initDate[0], initDate[1], initDate[2]));
+ me.absMax = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1);
- // If a String value was supplied, try to convert it to a proper Date object
- if (Ext.isString(value)) {
- me.value = me.rawToValue(value);
- }
+ me.store = me.createStore();
+ me.updateList();
me.callParent();
},
-<span id='Ext-form-field-Time-method-setMinValue'> /**
-</span> * Replaces any existing {@link #minValue} with the new time and refreshes the picker's range.
- * @param {Date/String} value The minimum time that can be selected
+<span id='Ext-picker-Time-method-setMinValue'> /**
+</span> * Set the {@link #minValue} and update the list of available times. This must be a Date object (only the time
+ * fields will be used); no parsing of String values will be done.
+ * @param {Date} value
*/
setMinValue: function(value) {
- var me = this,
- picker = me.picker;
- me.setLimit(value, true);
- if (picker) {
- picker.setMinValue(me.minValue);
- }
+ this.minValue = value;
+ this.updateList();
},
-<span id='Ext-form-field-Time-method-setMaxValue'> /**
-</span> * Replaces any existing {@link #maxValue} with the new time and refreshes the picker's range.
- * @param {Date/String} value The maximum time that can be selected
+<span id='Ext-picker-Time-method-setMaxValue'> /**
+</span> * Set the {@link #maxValue} and update the list of available times. This must be a Date object (only the time
+ * fields will be used); no parsing of String values will be done.
+ * @param {Date} value
*/
setMaxValue: function(value) {
- var me = this,
- picker = me.picker;
- me.setLimit(value, false);
- if (picker) {
- picker.setMaxValue(me.maxValue);
- }
- },
-
-<span id='Ext-form-field-Time-method-setLimit'> /**
-</span> * @private
- * Updates either the min or max value. Converts the user's value into a Date object whose
- * year/month/day is set to the {@link #initDate} so that only the time fields are significant.
- */
- setLimit: function(value, isMin) {
- var me = this,
- d, val;
- if (Ext.isString(value)) {
- d = me.parseDate(value);
- }
- else if (Ext.isDate(value)) {
- d = value;
- }
- if (d) {
- val = Ext.Date.clearTime(new Date(me.initDate));
- val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
- me[isMin ? 'minValue' : 'maxValue'] = val;
- }
- },
-
- rawToValue: function(rawValue) {
- return this.parseDate(rawValue) || rawValue || null;
- },
-
- valueToRaw: function(value) {
- return this.formatDate(this.parseDate(value));
- },
-
-<span id='Ext-form-field-Time-method-getErrors'> /**
-</span> * Runs all of Time's validations and returns an array of any errors. Note that this first
- * runs Text's validations, so the returned array is an amalgamation of all field errors.
- * The additional validation checks are testing that the time format is valid, that the chosen
- * time is within the {@link #minValue} and {@link #maxValue} constraints set.
- * @param {Mixed} value The value to get errors for (defaults to the current field value)
- * @return {Array} All validation errors for this field
- */
- getErrors: function(value) {
- var me = this,
- format = Ext.String.format,
- errors = me.callParent(arguments),
- minValue = me.minValue,
- maxValue = me.maxValue,
- date;
-
- value = me.formatDate(value || me.processRawValue(me.getRawValue()));
-
- if (value === null || value.length < 1) { // if it's blank and textfield didn't flag it then it's valid
- return errors;
- }
-
- date = me.parseDate(value);
- if (!date) {
- errors.push(format(me.invalidText, value, me.format));
- return errors;
- }
-
- if (minValue && date < minValue) {
- errors.push(format(me.minText, me.formatDate(minValue)));
- }
-
- if (maxValue && date > maxValue) {
- errors.push(format(me.maxText, me.formatDate(maxValue)));
- }
-
- return errors;
- },
-
- formatDate: function() {
- return Ext.form.field.Date.prototype.formatDate.apply(this, arguments);
+ this.maxValue = value;
+ this.updateList();
},
-<span id='Ext-form-field-Time-method-parseDate'> /**
+<span id='Ext-picker-Time-method-normalizeDate'> /**
</span> * @private
- * Parses an input value into a valid Date object.
- * @param {String/Date} value
+ * Sets the year/month/day of the given Date object to the {@link #initDate}, so that only
+ * the time fields are significant. This makes values suitable for time comparison.
+ * @param {Date} date
*/
- parseDate: function(value) {
- if (!value || Ext.isDate(value)) {
- return value;
- }
-
- var me = this,
- val = me.safeParse(value, me.format),
- altFormats = me.altFormats,
- altFormatsArray = me.altFormatsArray,
- i = 0,
- len;
-
- if (!val && altFormats) {
- altFormatsArray = altFormatsArray || altFormats.split('|');
- len = altFormatsArray.length;
- for (; i < len && !val; ++i) {
- val = me.safeParse(value, altFormatsArray[i]);
- }
- }
- return val;
+ normalizeDate: function(date) {
+ var initDate = this.initDate;
+ date.setFullYear(initDate[0], initDate[1], initDate[2]);
+ return date;
},
- safeParse: function(value, format){
- var me = this,
- utilDate = Ext.Date,
- parsedDate,
- result = null;
-
- if (utilDate.formatContainsDateInfo(format)) {
- // assume we've been given a full date
- result = utilDate.parse(value, format);
- } else {
- // Use our initial safe date
- parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format);
- if (parsedDate) {
- result = parsedDate;
- }
- }
- return result;
- },
-
- // @private
- getSubmitValue: function() {
- var me = this,
- format = me.submitFormat || me.format,
- value = me.getValue();
-
- return value ? Ext.Date.format(value, format) : null;
- },
-
-<span id='Ext-form-field-Time-method-createPicker'> /**
-</span> * @private
- * Creates the {@link Ext.picker.Time}
+<span id='Ext-picker-Time-method-updateList'> /**
+</span> * Update the list of available times in the list to be constrained within the {@link #minValue}
+ * and {@link #maxValue}.
*/
- createPicker: function() {
+ updateList: function() {
var me = this,
- picker = Ext.create('Ext.picker.Time', {
- selModel: {
- mode: 'SINGLE'
- },
- floating: true,
- hidden: true,
- minValue: me.minValue,
- maxValue: me.maxValue,
- increment: me.increment,
- format: me.format,
- ownerCt: this.ownerCt,
- renderTo: document.body,
- maxHeight: me.pickerMaxHeight,
- focusOnToFront: false
- });
+ min = me.normalizeDate(me.minValue || me.absMin),
+ max = me.normalizeDate(me.maxValue || me.absMax);
- me.mon(picker.getSelectionModel(), {
- selectionchange: me.onListSelect,
- scope: me
+ me.store.filterBy(function(record) {
+ var date = record.get('date');
+ return date >= min && date <= max;
});
-
- return picker;
},
-<span id='Ext-form-field-Time-method-onExpand'> /**
+<span id='Ext-picker-Time-method-createStore'> /**
</span> * @private
- * Enables the key nav for the Time picker when it is expanded.
- * TODO this is largely the same logic as ComboBox, should factor out.
+ * Creates the internal {@link Ext.data.Store} that contains the available times. The store
+ * is loaded with all possible times, and it is later filtered to hide those times outside
+ * the minValue/maxValue.
*/
- onExpand: function() {
+ createStore: function() {
var me = this,
- keyNav = me.pickerKeyNav,
- selectOnTab = me.selectOnTab,
- picker = me.getPicker(),
- lastSelected = picker.getSelectionModel().lastSelected,
- itemNode;
-
- if (!keyNav) {
- keyNav = me.pickerKeyNav = Ext.create('Ext.view.BoundListKeyNav', this.inputEl, {
- boundList: picker,
- forceKeyDown: true,
- tab: function(e) {
- if (selectOnTab) {
- if(me.picker.highlightedItem) {
- this.selectHighlighted(e);
- } else {
- me.collapse();
- }
- me.triggerBlur();
- }
- // Tab key event is allowed to propagate to field
- return true;
- }
+ utilDate = Ext.Date,
+ times = [],
+ min = me.absMin,
+ max = me.absMax;
+
+ while(min <= max){
+ times.push({
+ disp: utilDate.dateFormat(min, me.format),
+ date: min
});
- // stop tab monitoring from Ext.form.field.Trigger so it doesn't short-circuit selectOnTab
- if (selectOnTab) {
- me.ignoreMonitorTab = true;
- }
- }
- Ext.defer(keyNav.enable, 1, keyNav); //wait a bit so it doesn't react to the down arrow opening the picker
-
- // Highlight the last selected item and scroll it into view
- if (lastSelected) {
- itemNode = picker.getNode(lastSelected);
- if (itemNode) {
- picker.highlightItem(itemNode);
- picker.el.scrollChildIntoView(itemNode, false);
- }
- }
- },
-
-<span id='Ext-form-field-Time-method-onCollapse'> /**
-</span> * @private
- * Disables the key nav for the Time picker when it is collapsed.
- */
- onCollapse: function() {
- var me = this,
- keyNav = me.pickerKeyNav;
- if (keyNav) {
- keyNav.disable();
- me.ignoreMonitorTab = false;
- }
- },
-
-<span id='Ext-form-field-Time-method-onChange'> /**
-</span> * @private
- * Clears the highlighted item in the picker on change.
- * This prevents the highlighted item from being selected instead of the custom typed in value when the tab key is pressed.
- */
- onChange: function() {
- var me = this,
- picker = me.picker;
-
- me.callParent(arguments);
- if(picker) {
- picker.clearHighlight();
+ min = utilDate.add(min, 'mi', me.increment);
}
- },
-<span id='Ext-form-field-Time-method-onListSelect'> /**
-</span> * @private
- * Handles a time being selected from the Time picker.
- */
- onListSelect: function(list, recordArray) {
- var me = this,
- record = recordArray[0],
- val = record ? record.get('date') : null;
- me.setValue(val);
- me.fireEvent('select', me, val);
- me.picker.clearHighlight();
- me.collapse();
- me.inputEl.focus();
+ return Ext.create('Ext.data.Store', {
+ fields: ['disp', 'date'],
+ data: times
+ });
}
-});
+});
</pre>
</body>
</html>