/** * A time picker which provides a list of times from which to choose. This is used * by the {@link 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.picker.Time', { extend: 'Ext.view.BoundList', alias: 'widget.timepicker', requires: [ 'Ext.data.Store', 'Ext.Date' ], config: { /** * @hide * This class creates its own store based upon time range and increment configuration. */ store: true }, statics: { /** * @private * 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. */ createStore: function(format, increment) { var dateUtil = Ext.Date, clearTime = dateUtil.clearTime, initDate = this.prototype.initDate, times = [], min, max; min = clearTime(new Date(initDate[0], initDate[1], initDate[2])); max = dateUtil.add( clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1 ); while (min <= max) { times.push({ disp: dateUtil.dateFormat(min, format), date: min }); min = dateUtil.add(min, 'mi', increment); } return new Ext.data.Store({ model: Ext.picker.Time.prototype.modelType, data: times }); } }, /** * @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. */ /** * @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. */ /** * @cfg {Number} increment * The number of minutes between each time value in the list. */ increment: 15, /** * @cfg {String} [format=undefined] * 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. * @locale */ format: "g:i A", /** * 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. * @private */ displayField: 'disp', /** * Year, month, and day that all times will be normalized into internally. * @private */ initDate: [2008, 0, 1], componentCls: Ext.baseCSSPrefix + 'timepicker', alignOnScroll: false, /** * @cfg loadMask * @private */ loadMask: false, initComponent: function() { var me = this, dateUtil = Ext.Date, clearTime = dateUtil.clearTime, initDate = me.initDate; // 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 ); // Updates the range filter's filterFn according to our configured min and max me.updateList(); me.callParent(); }, setStore: function(store) { // TimePicker may be used standalone without being configured as a BoundList // by a Time field. // In this case, we have to create our own store. this.store = (store === true) ? Ext.picker.Time.createStore(this.format, this.increment) : store; }, /** * 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) { this.minValue = value; this.updateList(); }, /** * 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) { this.maxValue = value; this.updateList(); }, /** * @private * 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 */ normalizeDate: function(date) { var initDate = this.initDate; date.setFullYear(initDate[0], initDate[1], initDate[2]); return date; }, /** * Update the list of available times in the list to be constrained within the {@link #minValue} * and {@link #maxValue}. */ updateList: function() { var me = this, min = me.normalizeDate(me.minValue || me.absMin), max = me.normalizeDate(me.maxValue || me.absMax), filters = me.getStore().getFilters(), filter = me.rangeFilter; filters.beginUpdate(); if (filter) { filters.remove(filter); } filter = me.rangeFilter = new Ext.util.Filter({ filterFn: function(record) { var date = record.get('date'); return date >= min && date <= max; } }); filters.add(filter); filters.endUpdate(); }}, function() { this.prototype.modelType = Ext.define(null, { extend: 'Ext.data.Model', fields: ['disp', 'date'] });});