IntervalUI.js 9.16 KB
/**
 * Project   : AMDA-NG
 * Name      : IntervalUI.js
 * @class 	 amdaUI.IntervalUI
 * @extends  Ext.container.Container
 * @brief    common component to select interval
 * @author 	 Benjamin
 * @version  $Id: IntervalUI.js 2077 2014-02-11 11:33:36Z elena $
 * @todo Validations
 */

/**
config:
- durationLimit: The maximum value of the duration days field (9999 by default).
*/
Ext.define('amdaUI.IntervalUI', {
	extend: 'Ext.container.Container',

	alias: 'widget.intervalSelector',
	activeField : null,

	constructor: function(config) {
		this.init(config);
		this.callParent(arguments);
	},

	/**
		Set the start and stop date, and update the duration field.
		- startDate: A Extjs Date object representing the new start time.
		- stopDate: A Extjs Date object representing the new stop time.
		- return: None.
	*/
	setInterval : function(startDate,stopDate)
	{
		// get the search form
			var form = this.findParentByType('form').getForm();
			// get start field
			var startField = form.findField('startDate');
			// get stop field
			var stopField = form.findField('stopDate');

			if (startField != null)
			startField.setValue(startDate);

			if (stopField != null)
			stopField.setValue(stopDate);

			this.updateDuration();
	},

	/**
		Set the limits values of both startField and stopField date fields.
	*/
	setLimits: function(minValue, maxValue) {
		var form = this.findParentByType('form').getForm();
		var startField = form.findField('startDate');
		var stopField = form.findField('stopDate');

		if (startField != null) {
			startField.setMinValue(minValue);
			startField.setMaxValue(maxValue);
		}

		if (stopField != null) {
			stopField.setMinValue(minValue);
			stopField.setMaxValue(maxValue);
		}

		this.updateDuration();
	},
	
	setStartTime: function(startTime) {
		var form = this.findParentByType('form').getForm();
		var startField = form.findField('startDate');
		startField.setValue(startTime);
		this.updateDuration();
	},
	
	setStopTime: function(stopTime) {
		var form = this.findParentByType('form').getForm();
		var stopField = form.findField('stopDate');
		stopField.setValue(stopTime);
		this.updateDuration();
	},

	/**
		Get the start time field value.
		- return: A Extjs Date object representing the start time (null if the date is not valid).
	*/
	getStartTime : function()
	{
		// get the search form
			var form = this.findParentByType('form').getForm();
			// get start field
			var startField = form.findField('startDate');

			return startField.getValue();
	},

	/**
		Get the stop time field value.
		- return: A Extjs Date object representing the stop time (null if the date is not valid).
	*/
	getStopTime : function()
	{
		// get the search form
			var form = this.findParentByType('form').getForm();
			// get stop field
			var stopField = form.findField('stopDate');

			return stopField.getValue();
	},

	/*
		#### Private methods from here ####
	*/
	updateDuration: function() {
		// get the search form
		var form = this.findParentByType('form').getForm();
		// get start value
		var start = this.getStartTime();
		// get stop value
		var stop = this.getStopTime();
		// if duration computable
		if (stop != null && start != null) {
            if ( stop <= start ) {
                form.findField('stopDate').markInvalid('Stop Time  must be after Start Time');
            } else {
                if (!form.findField('stopDate').isValid())
                    form.findField('stopDate').clearInvalid();
            }
			// compute offset
			var zoneOffset = stop.getTimezoneOffset() - start.getTimezoneOffset();
			// compute duration
			var diff = stop - start - zoneOffset*60000;

			var durationDays = Math.floor(diff/86400000);
			// set all duration values
			form.findField('durationDay').setValue(durationDays);
			form.findField('durationHour').setValue(Math.floor(diff/3600000 % 24));
			form.findField('durationMin').setValue(Math.floor(diff/60000 % 60));
			form.findField('durationSec').setValue(Math.floor(diff/1000 % 60));

			if (durationDays > this.durationLimit) {
					form.findField('durationDay').markInvalid('Maximum interval is ' + this.durationLimit + ' days!');
			}
		} else {
			form.findField('durationDay').setValue('');
			form.findField('durationHour').setValue('');
			form.findField('durationMin').setValue('');
			form.findField('durationSec').setValue('');
		}
	},

	isValidDuration: function(){
		var form = this.findParentByType('form').getForm();
		return (
					form.findField('durationDay').isValid() &&
					form.findField('durationHour').isValid() &&
					form.findField('durationMin').isValid() &&
					form.findField('durationSec').isValid()
		);
	},

        isValid: function() {
            var form = this.findParentByType('form').getForm();
            var startField = form.findField('startDate');
            var stopField = form.findField('stopDate');
            if (!startField.isValid() || !stopField.isValid())
                return false;
            var start = this.getStartTime();
            var stop = this.getStopTime();
            if ( stop <= start ) {
                form.findField('stopDate').markInvalid('Stop Time  must be after Start Time');
                return false;
            }
            return true;
        },

	updateStop: function() {
		var form = this.findParentByType('form').getForm();
		var start = form.findField('startDate').getValue();

		var d = form.findField('durationDay').getValue();
		var h = form.findField('durationHour').getValue();
		var m = form.findField('durationMin').getValue();
		var s = form.findField('durationSec').getValue();
		var duration = (d?d:0)*86400 + (h?h:0)*3600 + (m?m:0)*60 + (s?s:0)
		var stop = Ext.Date.add(start, Ext.Date.SECOND, duration);
		
		if (Ext.Date.isDST(stop) && !Ext.Date.isDST(start))
			stop = Ext.Date.add(start, Ext.Date.SECOND, duration-3600);
		
		if (!Ext.Date.isDST(stop) && Ext.Date.isDST(start))
			stop = Ext.Date.add(start, Ext.Date.SECOND, duration+3600);
		
		form.findField('stopDate').setValue(stop);
	},

	onChangeStartField : function(field, newValue, oldValue)
	{
		if (field.isValid())  {
			// get the search form
			var form = this.findParentByType('form').getForm();
			// set to the stop datefield the newValue as minValue
			form.findField('stopDate').setMinValue(newValue);
			// if it's a user modification
			if (this.activeField == 'start')  {
				// launch the update of duration fields
				this.updateDuration();
			}
		}
	},

	onChangeStopField: function(field, newValue, oldValue)
	{
		if (field.isValid() && this.activeField == 'stop') {
			// launch the update of duration fields
			this.updateDuration();
		}
	},

	getDateField : function(fieldName,fieldText,fieldId,onChangeField)
	{
		return {
				xtype: 'datefield',
			//	margin : '10 0 5 5', // (top, right, bottom, left).
				name: fieldName, 
			//	width : 220,
				emptyText: 'YYYY/MM/DD hh:mm:ss',
				tip: 'Date formatted as YYYY/MM/DD hh:mm:ss',
				format: 'Y/m/d H:i:s',
			 	enforceMaxLength: true,
			 	maxLength: 19,
				fieldLabel: fieldText,
				labelAlign: 'left',
				labelWidth: 60,
				listeners: {
					change: onChangeField,
					focus: function(field) {
							this.activeField = fieldId;
					},
					render: function(c) {
							Ext.create('Ext.tip.ToolTip', { target: c.getEl(), html: c.tip });
					},
					scope : this
				}
		};
	},

	getStartField : function()
	{
		return this.getDateField('startDate','Start Time','start', this.onChangeStartField);
	},

	getStopField : function()
	{
		return this.getDateField('stopDate','Stop Time','stop', this.onChangeStopField);
	},

	getDurationField : function()
	{
		return {
			layout: {type: 'hbox', align: 'middle'},
		//	margin: 0,
			defaults: {
				xtype: 'numberfield',
				minValue: 0,
				maxLength: 2,
				enforceMaxLength: true,
				decimalPrecision: 0,
				allowExponential: false,
				autoStripChars: true,
				hideTrigger: true,
				labelAlign: 'left',
				width: 32,
				margin : '0 0 0 5',
				listeners: {
					change: function(field, newValue, oldValue) {
						var form = this.findParentByType('form').getForm();
						var start = form.findField('startDate').getValue();
						if (this.isValidDuration() && start!=null && this.activeField == 'duration')  {
								this.updateStop();
						}
					},
					focus: function(field) {
						this.activeField = 'duration';
					},
					render: function(c) {
						Ext.create('Ext.tip.ToolTip', { target: c.getEl(), html: c.tip });
					},
					scope : this
				}
			},
			items:[
					{ name: 'durationDay',  emptyText: 'Days', tip: 'Days',    maxValue: 73000, maxLength: 5, fieldLabel: 'Duration', labelWidth: 60, width: 110},
					{ name: 'durationHour', emptyText: 'Hrs',  tip: 'Hours',   maxValue: 23},
					{ name: 'durationMin',  emptyText: 'Mins', tip: 'Minutes', maxValue: 59},
					{ name: 'durationSec',  emptyText: 'Secs', tip: 'Seconds', maxValue: 59}
			]
		};
	},

	init : function(config) 
	{
		this.durationLimit = config.durationLimit == null ? 73000 : config.durationLimit; // Set duration limit to 200 years by default

		var me = this;
		var myConf = {
			border: false,
			plain: true,
			flex: 1,
			layout: 'anchor',
			defaults: { margin: '10 0 5 5', xtype : 'container'},
			items: [
				me.getStartField(),
				me.getStopField(),
				me.getDurationField()
			]
		};
		Ext.apply (this, Ext.apply(arguments, myConf));
	}
});