Threaded View

  1. #1
    Sencha User
    Join Date
    Dec 2010
    Posts
    47
    Vote Rating
    1
    eddow is on a distinguished road

      0  

    Default ja Ext.ux.form.DateTimeField

    ja Ext.ux.form.DateTimeField


    Hello,


    I needed some simple and strong date-time field (found some here but still problematic here and there)
    So I started with this one using only native ExtJs date and time edition abilities. It uses one input-text and has two triggers.
    It is basically one dateField who has a timeField bound to the same elements and triggered by the second trigger.


    dtsnap.png


    Hope it might help.


    Code:
    /* * 14Feb 2012 - DateTimeField
     * Francois Marie De Mey - eeddow@gmail
     * 
     * Date-time field with one common input box and two trigger/picker
     */
    (function() {
    	var 
    	//Combine a date and a time. Doesn't modify any 
    	combine = function(me, date, time) {
    		if('string'=== typeof date) date = me.parseDate(date);
    		if(!date) date = new Date();
    		if('string'=== typeof time) time = me.parseDate(time);
    		if(!time) time = new Date();
    		var rv = new Date(date);
    		rv.setHours(time.getHours());
    		rv.setMinutes(time.getMinutes());
    		rv.setSeconds(time.getSeconds());
    		return rv;
    	},
    	//Trick the 'format' option for some timeField functions needing only time to be used
    	oldFormatFunction = function(methodName) {
    		return function() {
    			var me = this, rv, dateCtl = me.datetimeField;
    			me.format = dateCtl.timeFormat;
    			rv = Ext.form.TimeField.prototype[methodName].apply(me, arguments);
    			me.format = dateCtl.format;					
    			return rv;
    		};
    	};
    	
    	Ext.define('Ext.ux.form.DateTimeField', {
    		extend: 'Ext.form.DateField',
    		alias: 'widget.datetimefield',
    		requires: ['Ext.form.TimeField'],
    
    
    		trigger2Cls: Ext.baseCSSPrefix + 'form-time-trigger',
    
    
    		/**
    		 * @cfg {Number} pickerMaxHeight
    		 * The maximum height of the {@link Ext.picker.Time} dropdown.
    		 */
    		
    		/**
    		 * @cfg {String} minTimeText
    		 * The error text to display when the entered time is before {@link #minTime}.
    		 */
    
    
    		/**
    		 * @cfg {Date/String} minTime
    		 * 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}.
    		 */
    
    
    		/**
    		 * @cfg {String} maxTimeText
    		 * The error text to display when the entered time is after {@link #maxTime}.
    		 */
    		/**
    		 * @cfg {Date/String} maxTime
    		 * 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}.
    		 */
    		/**
    		 * @cfg {Number} increment
    		 * The number of minutes between each time value in the list.
    		 */
    		/**
    		 * @cfg {String} format
    		 * The default date format string which can be overriden for localization support. The format must be valid
    		 * according to {@link Ext.Date#parse}.
    		 */
    		format : "m/d/Y H:i",
    		/**
    		 * @cfg {String} format
    		 * The default time format string used to express only the time part. The format must be valid
    		 * according to {@link Ext.Date#parse}.
    		 */
    		timeFormat: "H:i",
    		/**
    		 * @cfg {String} altFormats
    		 * Multiple date formats separated by "|" to try when parsing a user input value and it does not match the defined
    		 * format.
    		 */
    		altFormats : "m/d/Y H:i|n/j/Y H:i|n/j/y H:i|m/j/y H:i|n/d/y H:i|m/j/Y H:i|n/d/Y H:i|m-d-y H:i|m-d-Y H:i|m/d H:i|m-d H:i|md H:i|mdy H:i|mdY H:i|d H:i|Y-m-d H:i|n-j H:i|n/j H:i",
    
    
    		initComponent: function() {
    			var me = this, elm, config = {
    				datetimeField: me,
    				
    				//share the format
    				format: me.format,
    				altFormats: me.altFormats,
    				
    				//Straight forwards
    				minText: me.minTimeText,
    				maxText: me.maxTimeText,
    				
    				//Don't set the value, juste the "time" part of the value
    				onListSelect: function(list, recordArray) {
    					var me = this,
    						record = recordArray[0],
    						val = record ? record.get('date') : null;
    					me.datetimeField.setValue(combine(me, me.getValue(), val));
    					me.fireEvent('select', me, val);
    					me.picker.clearHighlight();
    					me.collapse();
    					me.inputEl.focus();
    				},
    				
    				//Oops... we must use the 'time' format some times
    				createPicker: oldFormatFunction('createPicker'),
    				setLimit: oldFormatFunction('setLimit')
    			}, forward = {
    				minValue: me.minTime,
    				maxValue: me.maxTime,
    				increment: me.increment,
    				pickerMaxHeight: me.pickerMaxHeight
    			};
    			for(elm in forward)
    				if({}.u!== forward[elm] && forward.hasOwnProperty(elm))
    					config[elm] = forward[elm];
    			//Create the "virtual" time field
    			me.timeField = new Ext.form.TimeField(config);
    			this.callParent();
    		},
    		onRender: function() {
    			var me = this, triggers;
    
    
    
    
    			me.callParent(arguments);
    			triggers = me.triggerEl;
    
    
    			me.dateTrigger = triggers.item(0);
    			me.timeTrigger = triggers.item(1);
    			
    			Ext.apply(me.timeField, {
    				rendered: true,
    				el: me.el,
    				inputEl: me.inputEl,
    				bodyEl: me.bodyEl,
    				errorEl: me.errorEl
    			});
    			
    		},
    		mimicBlur: function(e) {
    			var me = this,
    				picker = me.timeField.picker;
    			// ignore mousedown events within the picker element
    			if (!picker || !e.within(picker.el, false, true)) {
    				me.callParent(arguments);
    			}
    		},
    
    
    		//Suddenly, a wide trigger appears...
    		getTriggerWidth: function() {
    			return this.hideTrigger || this.readOnly ? 0 : this.timeTrigger.getWidth() + this.dateTrigger.getWidth() + this.triggerWrap.getFrameWidth('lr');
    		}, 
    
    
    		//Manually expand our "virtual" time field
    		onTrigger2Click: function() {
    			var me=this;
    			me.collapse();
    			me.timeField.onTriggerClick();
    		},
    		onTriggerClick: function() {
    			var me=this;
    			me.timeField.collapse();
    			me.callParent(arguments);
    		},
    		
    		//Don't set the value, juste the "date" part of the value
    		onSelect: function(m, d) {
    			var me = this;
    
    
    			me.setValue(combine(me, d, me.getValue()));
    			me.fireEvent('select', me, d);
    			me.collapse();
    		},
    		
    		//Combinations
    		getErrors: function(value) {
    			var me = this,
    				format = Ext.String.format,
    				errors = me.callParent(arguments),
    				minValue = me.minTime,
    				maxValue = me.maxTime,
    				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) {
    				//avoid double format error
    				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;
    		},
    		setValue: function() {
    			var me = this, args = arguments, timeField = me.timeField;
    			me.callParent(args);
    			return timeField.setValue.apply(timeField, arguments);
    		},
    		
    		//Straight forwards
    		setMaxTime: function() {
    			var timeField = this.timeField;
    			return timeField.setMaxValue.apply(timeField, arguments);
    		},
    		setMinTime: function() {
    			var timeField = this.timeField;
    			return timeField.setMinValue.apply(timeField, arguments);
    		}
    	
    	});
    })();
    Last edited by eddow; 15 Feb 2012 at 4:17 AM. Reason: bug-fix for in-column editor