Ext.namespace('Ext.ux.form'); /** * Ext.ux.form.DateTime Extension Class for Ext 2.x Library * * @author Ing. Jozef Sakalos * @copyright (c) 2008, Ing. Jozef Sakalos * @version $Id: Ext.ux.form.DateTime.js 645 2008-01-27 21:53:01Z jozo $ * * @class Ext.ux.form.DateTime * @extends Ext.form.Field * * @history * 2008-1-31 Jack Slocum * Updated for reformatting and code edits */ Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, { defaultAutoCreate: { tag: 'input', type: 'hidden' }, dateWidth: 135, timeWidth: 100, dtSeparator: ' ', hiddenFormat: 'Y-m-d H:i:s', otherToNow: true, timePosition: 'right', initComponent: function(){ // call parent initComponent Ext.ux.form.DateTime.superclass.initComponent.call(this); // create DateField var dateConfig = Ext.apply({}, { id: this.id + '-date', format: this.dateFormat, width: this.dateWidth, listeners: { blur: { scope: this, fn: this.onBlur }, focus: { scope: this, fn: this.onFocus } } }, this.dateConfig); this.df = new Ext.form.DateField(dateConfig); delete (this.dateFormat); // create TimeField var timeConfig = Ext.apply({}, { id: this.id + '-time', format: this.timeFormat, width: this.timeWidth, listeners: { blur: { scope: this, fn: this.onBlur }, focus: { scope: this, fn: this.onFocus } } }, this.timeConfig); this.tf = new Ext.form.TimeField(timeConfig); delete (this.timeFormat); // relay events this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']); this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']); }, onRender: function(ct, position){ if (this.isRendered) { return; } // render underlying field Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position); // render DateField and TimeField // create bounding table if ('below' === this.timePosition) { var t = Ext.DomHelper.append(ct, { tag: 'table', style: 'border-collapse:collapse', children: [{ tag: 'tr', children: [{ tag: 'td', style: 'padding-bottom:1px', cls: 'ux-datetime-date' }] }, { tag: 'tr', children: [{ tag: 'td', cls: 'ux-datetime-time' }] }] }, true); } else { var t = Ext.DomHelper.append(ct, { tag: 'table', style: 'border-collapse:collapse', children: [{ tag: 'tr', children: [{ tag: 'td', style: 'padding-right:4px', cls: 'ux-datetime-date' }, { tag: 'td', cls: 'ux-datetime-time' }] }] }, true); } this.tableEl = t; this.wrap = t.wrap({ cls: 'x-form-field-wrap' }); this.wrap.on("mousedown", this.onMouseDown, this, { delay: 10 }); // render DateField & TimeField this.df.render(t.child('td.ux-datetime-date')); this.tf.render(t.child('td.ux-datetime-time')); if (Ext.isIE && Ext.isStrict) { t.select('input').applyStyles({ top: 0 }); } this.on('specialkey', this.onSpecialKey, this); this.df.el.swallowEvent(['keydown', 'keypress']); this.tf.el.swallowEvent(['keydown', 'keypress']); // create errorIcon for side invalid if ('side' === this.msgTarget) { var elp = this.el.findParent('.x-form-element', 10, true); this.errorIcon = elp.createChild({ cls: 'x-form-invalid-icon' }); this.df.errorIcon = this.errorIcon; this.tf.errorIcon = this.errorIcon; } this.isRendered = true; }, getPositionEl: function(){ return this.wrap; }, getResizeEl: function(){ return this.wrap; }, adjustSize: Ext.BoxComponent.prototype.adjustSize, alignErrorIcon: function(){ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); }, onSpecialKey: function(t, e){ if (e.getKey() == e.TAB) { if (t === this.df && !e.shiftKey) { e.stopEvent(); this.tf.focus(); } if (t === this.tf && e.shiftKey) { e.stopEvent(); this.df.focus(); } } }, setSize: function(w, h){ if (!w) { return; } if ('below' == this.timePosition) { this.df.setSize(w, h); this.tf.setSize(w, h) if (Ext.isIE) { this.df.el.up('td').setWidth(w); this.tf.el.up('td').setWidth(w); } } else { this.df.setSize(w - this.timeWidth - 4, h); this.tf.setSize(this.timeWidth, h); if (Ext.isIE) { this.df.el.up('td').setWidth(w - this.timeWidth - 4); this.tf.el.up('td').setWidth(this.timeWidth); } } }, setValue: function(val){ if (!val) { this.setDate(''); this.setTime(''); this.updateValue(); return; } // clear cross frame AIR nonsense val = new Date(val.getTime()); var da, time; if (Ext.isDate(val)) { this.setDate(val); this.setTime(val); this.dateValue = new Date(val); } else { da = val.split(this.dtSeparator); this.setDate(da[0]); if (da[1]) { this.setTime(da[1]); } } this.updateValue(); }, getValue: function(){ // create new instance of date return this.dateValue ? new Date(this.dateValue) : ''; }, onMouseDown: function(e){ // just to prevent blur event when clicked in the middle of fields this.wrapClick = 'td' === e.target.nodeName.toLowerCase(); }, onFocus: function(){ if (!this.hasFocus) { this.hasFocus = true; this.startValue = this.getValue(); this.fireEvent("focus", this); } }, onBlur: function(f){ // called by both DateField and TimeField blur events // revert focus to previous field if clicked in between if (this.wrapClick) { f.focus(); this.wrapClick = false; } // update underlying value if (f === this.df) { this.updateDate(); } else { this.updateTime(); } this.updateHidden(); // fire events later (function(){ if (!this.df.hasFocus && !this.tf.hasFocus) { var v = this.getValue(); if (String(v) !== String(this.startValue)) { this.fireEvent("change", this, v, this.startValue); } this.hasFocus = false; this.fireEvent('blur', this); } }).defer(100, this); }, updateDate: function(){ var d = this.df.getValue(); if (d) { if (!Ext.isDate(this.dateValue)) { this.initDateValue(); if (!this.tf.getValue()) { this.setTime(this.dateValue); } } this.dateValue.setFullYear(d.getFullYear()); this.dateValue.setMonth(d.getMonth()); this.dateValue.setDate(d.getDate()); } else { this.dateValue = ''; this.setTime(''); } }, updateTime: function(){ var t = this.tf.getValue(); if (t && !Ext.isDate(t)) { t = Date.parseDate(t, this.tf.format); } if (t && !this.df.getValue()) { this.initDateValue(); this.setDate(this.dateValue); } if (Ext.isDate(this.dateValue)) { if (t) { this.dateValue.setHours(t.getHours()); this.dateValue.setMinutes(t.getMinutes()); this.dateValue.setSeconds(t.getSeconds()); } else { this.dateValue.setHours(0); this.dateValue.setMinutes(0); this.dateValue.setSeconds(0); } } }, initDateValue: function(){ this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0); }, updateHidden: function(){ if (this.isRendered) { var value = Ext.isDate(this.dateValue) ? this.dateValue.format(this.hiddenFormat) : ''; this.el.dom.value = value; } }, updateValue: function(){ this.updateDate(); this.updateTime(); this.updateHidden(); return; }, setDate: function(date){ this.df.setValue(date); }, setTime: function(date){ this.tf.setValue(date); }, isValid: function(){ return this.df.isValid() && this.tf.isValid(); }, validate: function(){ return this.df.validate() && this.tf.validate(); }, focus: function(){ this.df.focus(); }, onDisable : function(){ if(this.rendered){ this.df.disable(); this.tf.disable(); } }, onEnable : function(){ if(this.rendered){ this.df.enable(); this.tf.enable(); } } }); // register xtype Ext.reg('xdatetime', Ext.ux.form.DateTime);