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);