X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/source/Time2.html?ds=inline diff --git a/docs/source/Time2.html b/docs/source/Time2.html index 5a9b0788..fcb11d8c 100644 --- a/docs/source/Time2.html +++ b/docs/source/Time2.html @@ -3,8 +3,8 @@
/** - * @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> +/** + * 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'], - - /** - * @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', - - /** - * @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). - */ - - /** - * @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'], - /** - * @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}'). + /** + * @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}", - /** - * @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}'). + /** + * @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}", - /** - * @cfg {String} invalidText - * The error text to display when the time in the field is invalid (defaults to - * '{value} is not a valid time'). + /** + * @cfg {Number} increment + * The number of minutes between each time value in the list. */ - invalidText : "{0} is not a valid time", + increment: 15, - /** + /** * @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", - /** - * @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>). - */ - - /** - * @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'). + /** + * @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', - /** - * @cfg {Number} increment - * The number of minutes between each time value in the list (defaults to 15). - */ - increment: 15, - - /** - * @cfg {Number} pickerMaxHeight - * The maximum height of the {@link Ext.picker.Time} dropdown. Defaults to 300. + /** + * @private + * Year, month, and day that all times will be normalized into internally. */ - pickerMaxHeight: 300, + initDate: [2008,0,1], - /** - * @cfg {Boolean} selectOnTab - * Whether the Tab key should select the currently highlighted item. Defaults to <tt>true</tt>. - */ - selectOnTab: true, + componentCls: Ext.baseCSSPrefix + 'timepicker', - /** - * @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. + /** + * @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(); }, - /** - * 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 + /** + * 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(); }, - /** - * 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 + /** + * 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); - } - }, - - /** - * @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)); - }, - - /** - * 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(); }, - /** + /** * @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; - }, - - /** - * @private - * Creates the {@link Ext.picker.Time} + /** + * 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; }, - /** + /** * @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); - } - } - }, - - /** - * @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; - } - }, - - /** - * @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); } - }, - /** - * @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 + }); } -}); +});