Ext.ns('Zarafa.common.plugins'); /** * @class Zarafa.common.plugins.TimeSpinner * @extends Zarafa.common.plugins.SpinnerPlugin * @ptype zarafa.timespinner * Extension to the {@link Zarafa.common.plugins.SpinnerPlugin} object, * to correctly parse times. This is used by the * {@link Zarafa.common.ui.SpinnerField SpinnerField} */ Zarafa.common.plugins.TimeSpinner = Ext.extend(Zarafa.common.plugins.SpinnerPlugin, { /** * @cfg {String} format The string format which is applied for * displaying the time in the {@link Zarafa.common.ui.SpinnerField SpinnerField}. */ format : _('G:i'), /** * @cfg {String} alternateIncrementField The Date field which must be incremented * when the alternate increment/decrement option is used (default: Date.HOUR). */ alternateIncrementField : Date.HOUR, /** * @cfg {String} incrementField The Date field which must be incremented when the * normal increment/decrement option is used (default: Date.MINUTE). */ incrementField: Date.MINUTE, /** * @constructor * @param {Object} config Configuration object */ constructor : function(config) { Ext.applyIf(this, config); Zarafa.common.plugins.TimeSpinner.superclass.constructor.call(this, config); }, /** * Initializes the {@link Zarafa.common.ui.SpinnerField SpinnerField} to which * this plugin has been hooked. * @param {Zarafa.common.ui.SpinnerField} The parent field to which this component is connected */ init : function(field) { Zarafa.common.plugins.TimeSpinner.superclass.init.call(this, field); // Enforce all default values to the date format. if (Ext.isDefined(field.defaultValue) && !Ext.isDate(field.defaultValue)) { field.defaultValue = Date.parseDate(field.defaultValue, this.format); } if (Ext.isDefined(field.minValue) && !Ext.isDate(field.minValue)) { field.minValue = Date.parseDate(field.minValue, this.format); } if (Ext.isDefined(field.maxValue) && !Ext.isDate(field.maxValue)) { field.maxValue = Date.parseDate(field.maxValue, this.format); } // Initialize our values this.dateValue = field.defaultValue; if (Ext.isDate(this.dateValue)) { field.value = this.dateValue.format(this.format); } // Update the getValue/setValue functions with our custom // functions which handle the Date value type. this.setStringValue = field.setValue.createDelegate(field); this.getStringValue = field.getValue.createDelegate(field); field.setValue = this.setValue.createDelegate(this); field.getValue = this.getValue.createDelegate(this); field.isValidTimeString = this.isValidTimeString.createDelegate(this); }, /** * Reference to the original {@link Ext.form.Field#setValue} function * for setting the inner value as String. * @param {String} value The value to set * @private */ setStringValue : Ext.emptyFn, /** * Reference to the original {@link Ext.form.Field#getValue} function * for getting the inner value as String. * @return {String} value The value to set * @private */ getStringValue : Ext.emptyFn, /** * Sets a data value into the field and validates it. * To set the value directly without validation see {@link Ext.form.Field#setRawValue}. * @param {Date/String} value The value to set * @private */ setValue : function(value) { if (!Ext.isDefined(value) || Ext.isEmpty(value)) { // If no value is provided, we clear the field. this.dateValue = null; this.setStringValue(''); } else if (Ext.isDate(value)) { // The value is a date, clone it to obtain a local copy. this.dateValue = value.clone(); this.setStringValue(value.format(this.format)); } else if (Ext.isDate(this.dateValue)) { // The value is a String, but the dateValue is a Date. // Use the dateValue to determine the date (Day, Month, Year) // part which must be applied to the value (which only contains hours and minutes). var tmpDate = Date.parseDate(value, this.format); value = this.dateValue.clone(); value.setHours(tmpDate.getHours()); value.setMinutes(tmpDate.getMinutes()); this.dateValue = value; this.setStringValue(value.format(this.format)); } else { // The value is a String, dateValue is useless. // We parse the date and assume that the Day, Month, Year // should be set for today. this.dateValue = Date.parseDate(value, this.format); this.setStringValue(value); } }, /** * Returns the normalized data value (undefined or emptyText will be returned as ''). * To return the raw value see {@link Ext.form.Field#getRawValue}. * @return {Date} The selected Date * @private */ getValue : function() { var stringValue = this.isValidTimeString() ? this.getStringValue() : this.field.value; if (Ext.isEmpty(stringValue) || Ext.isEmpty(this.dateValue)) { return null; } var dateValue = Date.parseDate(stringValue, this.format); this.dateValue.setHours(dateValue.getHours()); this.dateValue.setMinutes(dateValue.getMinutes()); return this.dateValue.clone(); }, /** * The default spin action when the value inside the * {@link Zarafa.common.ui.SpinnerField SpinnerField} must be changed. * * @param {Boolean} down True when the value must be decreased * @param {Boolean} alternate True when the alternate change has been requested * @private */ spin : function(down, alternate) { var oldValue; if (this.field.rendered) { this.field.onFocus(); } // Always parse the value from the parent field, in case the user typed in an update var v = this.field.getValue(); // Determine the method to change the value var incr = (alternate === true) ? this.field.alternateIncrementValue : this.field.incrementValue; var incrField = (alternate === true) ? this.alternateIncrementField : this.incrementField; oldValue = v; if (v) { v = v.add(incrField, down ? (-1 * incr) : incr); } // When spinning up, we could at one point increase the time into the Daylight Saving area. // With switch to Daylight savings between 2 and 3 AM, all values within that lost hour, are // rounded down by Javascript. Meaning that we can't use the spinbox to step over the given // hour. So when the new value is lower then the old value, while we are spinning down, we // assume this is the DST switch, and we must add 2 hours to step over the lost hour and // make the step as logical as possible. if (!down && v && (v <= oldValue)) { v = v.add(Date.HOUR, 2); } v = (!Ext.isDate(v)) ? this.field.defaultValue : v; v = this.fixBoundries(v); // Format the Date back into a string for displaying. this.field.setValue(v); }, /** * Update the value to a correctly formatted float. * Disable this function, since it must be a noop for * Date values. * @param {Mixed} value The value to fix * @private */ fixPrecision : function(value) { return value; }, /** * Function which is used to validate time string. * It will return true if the value of the field is in a HH:MM format. * @returns {boolean} True if time string value is valid, false otherwise */ isValidTimeString : function () { var regEx = /^([0-1]?[0-9]|2[0-4]):([0-5][0-9])(:[0-5][0-9])?$/; return regEx.test(this.getStringValue()); } }); // Register as plugin, so that it can be used using lazy loading // with the Zarafa.common.ui.SpinnerField Ext.preg('zarafa.timespinner', Zarafa.common.plugins.TimeSpinner);