PDA

View Full Version : Ext.ux.form.field.DateTime



atian25
22 May 2011, 5:48 PM
http://www.sencha.com/forum/attachment.php?attachmentid=26204&d=1306115198

it's a beta version, and some question: (help~plz)
1.if i don't set width/height, then DateTime in toolbar is missing
2. cant show correct width in RowEditing plugin
http://i.stack.imgur.com/PyumG.png



Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins: {
field: 'Ext.form.field.Field'
},
alias: 'widget.datetimefield',
layout: 'hbox',
width: 200,
height: 22,
combineErrors: true,
msgTarget :'side',

dateCfg:{},
timeCfg:{},

initComponent: function() {
var me = this;
me.buildField();
me.callParent();
this.dateField = this.down('datefield')
this.timeField = this.down('timefield')
me.initField();
},

//@private
buildField: function(){
this.items = [
Ext.apply({
xtype: 'datefield',
format: 'Y-m-d',
width: 100
},this.dateCfg),
Ext.apply({
xtype: 'timefield',
format: 'H:i',
width: 80
},this.timeCfg)
]
},

getValue: function() {
var value,date = this.dateField.getSubmitValue(),time = this.timeField.getSubmitValue();
if(date){
if(time){
var format = this.getFormat()
value = Ext.Date.parse(date + ' ' + time,format)
}else{
value = this.dateField.getValue()
}
}
return value
},

setValue: function(value){
this.dateField.setValue(value)
this.timeField.setValue(value)
},

getSubmitData: function(){
var value = this.getValue()
var format = this.getFormat()
return value ? Ext.Date.format(value, format) : null;
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format)
}
})

atian25
24 May 2011, 5:28 PM
anyone could help? thanks

Dmoney
26 Jun 2011, 8:31 PM
This extension works well for what I needed in a form, however I'm having trouble setting the value of the fields. My form is bound to a grid and the model for my store has a value defined like this



{name: 'pubDate',
mapping: 'pubDate'
}


when I select a record in the grid the datetimefield does not display the value. the value in the record is like this : "pubDate":"2011-06-26 01:00:00"

what am I doing wrong?

ontho
27 Jun 2011, 8:25 AM
Thanks for this code! I've taken the liberty to extend the code a bit, but be careful, it has not been tested very much till now.

Added features:
- A button to set "now" and clear the value (set btnNowText:'' to hide the button).
- A dateTimeFormat which makes the submitted value format more flexible. It's also used as the input for setValue (@Dmoney: Does this solve your problem?).

There are 3 known issues:
- The button width changes when the button text changes which looks a bit strange in my eyes (Any idea how to make the button stay on the widest width concerning both possible texts)?
- I'm not quite sure if this getSubmitData-thing is a bug.
- The readOnly-config doesn't work so far.



Ext.namespace('Ext.ux.form');

Ext.define('Ext.ux.form.DateTime',
{
extend:'Ext.form.FieldContainer'
,mixins:
{ field: 'Ext.form.field.Field'
}
,alias: 'widget.xdatetime'

,combineErrors: true
,msgTarget: 'under'

,layout: 'hbox'
,dateFormat: 'Y-m-d',
,timeFormat: 'H:i:s'
,dateTimeFormat: 'Y-m-d H:i:s'
,dateCfg:{}
,timeCfg:{}
,btnCfg:{}

,btnNowText: 'Set now'
,btnClearText: 'Clear'

,readOnly: false // ReadOnly

// internal
,dateValue: null // Holds the actual date
,dateField: null
,timeField: null
,btnField: null

,initComponent: function()
{ var me = this;
me.items = me.itmes || [];
me.items.push(Ext.apply(
{ xtype: 'datefield',
format: me.dateFormat,
flex: 1,
submitValue: false,
listeners:
{ change: Ext.bind(this.onChange, this)
}
}, me.dateCfg));
me.items.push(Ext.apply(
{ xtype: 'timefield',
format: me.timeFormat,
flex: 1,
submitValue: false,
listeners:
{ change: Ext.bind(this.onChange, this)
}
}, me.timeCfg));

if (me.btnNowText && !me.readOnly)
{ me.items.push(
Ext.apply(
{ xtype: 'button',
text: me.btnNowText,
flex: 0,
autoWidth: false,
handler: Ext.bind(this.onBtnClick, this)
})
);
}

me.callParent();

me.dateField = me.down('datefield');
me.timeField = me.down('timefield');
me.btnField = me.down('button');
me.initField();
}

,getValue: function()
{ var value = null,
date = this.dateField.getSubmitValue(),
time = this.timeField.getSubmitValue();

if(date)
{ if(time)
{ var format = this.getFormat()
value = Ext.Date.parse(date + ' ' + time, format)
}
else
{ value = this.dateField.getValue()
}
}
return value;
}

,getSubmitValue: function()
{ var value = this.getValue();
return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
}

,setValue: function(value)
{ if (Ext.isString(value))
{ value = Ext.Date.parse(value, this.dateTimeFormat);
}
this.dateField.setValue(value);
this.timeField.setValue(value);
}

,getFormat: function()
{ return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format)
}

,updateBtn: function()
{ if (!this.btnField) return;
if (this.getSubmitValue() === null)
{ this.btnField.setText(this.btnNowText);
}
else
{ this.btnField.setText(this.btnClearText);
}
}

,onBtnClick: function(btn, e)
{ if (this.getSubmitValue() == null)
{ this.setValue(new Date());
}
else
{ this.setValue(null);
}
}

,onChange: function( field, newValue, oldValue, options )
{ this.updateBtn();
}

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
,getSubmitData: function() {
var me = this,
data = null;
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});

Dmoney
27 Jun 2011, 8:56 AM
@ontho

Thanks for posting your your code. Your changes fixed my problem and everything is working great! The clear button and Set Now feature is a great addition as well. Thanks Again!

jonaldomo
28 Jun 2011, 9:20 AM
Both versions I get the errors:

Uncaught TypeError: Object [object Object] has no method 'getDesiredWidth'
Uncaught TypeError: Cannot call method 'setStyle' of undefined


I am using 4.0.2a, any thoughts?

Thanks in advanced.

ontho
28 Jun 2011, 10:31 AM
I am using 4.0.2a as well and it's working - could you perhaps post a code which reproduces the errors?

jakob.ketterl
29 Jun 2011, 12:11 AM
i've worked a little on this to get it to display in a cell editing grid under 4.0.2

i've stripped out the button since i didn't need it and it only caused me pain, sorry for that :)

it's most probably not perfect, but maybe this will be of use to somebody.
here's the code:


Ext.define('Ext.ux.form.field.DateTime',
{
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',

combineErrors: true,
msgTarget: 'under',

layout: 'hbox',
dateFormat: 'Y-m-d',
timeFormat: 'H:i:s',
dateTimeFormat: 'Y-m-d H:i:s',
dateCfg:{},
timeCfg:{},

readOnly: false,

// internal
dateValue: null, // Holds the actual date
dateField: null,
timeField: null,

initComponent: function(){
var me = this;
me.items = me.itmes || [];

me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
submitValue:false
}, me.dateCfg));
me.items.push(me.dateField);

me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
submitValue:false
}, me.timeCfg));
me.items.push(me.timeField);

for (var i = 0; i < me.items.length; i++) {
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
me.items[i].on('specialkey', function(field, event){
var key = event.getKey(),
tab = key == event.TAB;

if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}

me.fireEvent('specialkey', field, event);
});
}

me.callParent();

// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom:{},
swallowEvent:function(){}
};

me.initField();
},

focus:function(){
this.callParent();
this.dateField.focus();
},

onItemFocus:function(item){
if (this.blurTask) this.blurTask.cancel();
this.focussedItem = item;
},

onItemBlur:function(item){
var me = this;
if (item != me.focussedItem) return;
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me);
});
me.blurTask.delay(100);
},

getValue: function(){
var value = null,
date = this.dateField.getSubmitValue(),
time = this.timeField.getSubmitValue();

if(date)
{
if(time)
{
var format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
}
else
{
value = this.dateField.getValue();
}
}
return value;
},

getSubmitValue: function(){
var value = this.getValue();
return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
},

setValue: function(value){
if (Ext.isString(value))
{
value = Ext.Date.parse(value, this.dateTimeFormat);
}
this.dateField.setValue(value);
this.timeField.setValue(value);
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
},

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this,
data = null;
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});

jonaldomo
29 Jun 2011, 6:09 AM
I am using 4.0.2a as well and it's working - could you perhaps post a code which reproduces the errors?

I discovered that my problem was that I was using CellEditing. Once I switched to RowEditing it worked fine. Any simple fix to make it work with CellEditing?

I receive the error:
Uncaught TypeError: Cannot read property 'dom' of undefined

zombeerose
29 Jun 2011, 7:31 AM
* fixed the "itmes" spelling error.
* renamed dateCfg/timeCfg to dateConfig/timeConfig for consistency with Ext framework.
* added class/config docs.



/**
* @class Ext.ux.form.field.DateTime
* @extends Ext.form.FieldContainer
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
* @author ontho (http://www.sencha.com/forum/member.php?285806-ontho)
* @author jakob.ketterl (http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
*/
Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',

//configurables

combineErrors: true,
msgTarget: 'under',
layout: 'hbox',
readOnly: false,

/**
* @cfg {String} dateFormat
* The default is 'Y-m-d'
*/
dateFormat: 'Y-m-d',
/**
* @cfg {String} timeFormat
* The default is 'H:i:s'
*/
timeFormat: 'H:i:s',
/**
* @cfg {String} dateTimeFormat
* The format used when submitting the combined value.
* Defaults to 'Y-m-d H:i:s'
*/
dateTimeFormat: 'Y-m-d H:i:s',
/**
* @cfg {Object} dateConfig
* Additional config options for the date field.
*/
dateConfig:{},
/**
* @cfg {Object} timeConfig
* Additional config options for the time field.
*/
timeConfig:{},


// properties

dateValue: null, // Holds the actual date
/**
* @property dateField
* @type Ext.form.field.Date
*/
dateField: null,
/**
* @property timeField
* @type Ext.form.field.Time
*/
timeField: null,

initComponent: function(){
var me = this;
me.items = me.items || [];

me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
submitValue:false
}, me.dateConfig));
me.items.push(me.dateField);

me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
submitValue:false
}, me.timeConfig));
me.items.push(me.timeField);

for (var i = 0; i < me.items.length; i++) {
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
me.items[i].on('specialkey', function(field, event){
var key = event.getKey(),
tab = key == event.TAB;

if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}

me.fireEvent('specialkey', field, event);
});
}

me.callParent();

// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom:{},
swallowEvent:function(){}
};

me.initField();
},

focus:function(){
this.callParent();
this.dateField.focus();
},

onItemFocus:function(item){
if (this.blurTask) this.blurTask.cancel();
this.focussedItem = item;
},

onItemBlur:function(item){
var me = this;
if (item != me.focussedItem) return;
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me);
});
me.blurTask.delay(100);
},

getValue: function(){
var value = null,
date = this.dateField.getSubmitValue(),
time = this.timeField.getSubmitValue();

if(date)
{
if(time)
{
var format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
}
else
{
value = this.dateField.getValue();
}
}
return value;
},

getSubmitValue: function(){
var value = this.getValue();
return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
},

setValue: function(value){
if (Ext.isString(value))
{
value = Ext.Date.parse(value, this.dateTimeFormat);
}
this.dateField.setValue(value);
this.timeField.setValue(value);
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
},

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this,
data = null;
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});

//eo file

zombeerose
20 Jul 2011, 10:03 AM
* Removed the 'dateTimeFormat' config - use dateFormat & timeFormat instead.
* Exclude date & time fields from form query operations. Otherwise, calling form.getForm().getFieldValues(false) returns field containers and sub-fields in values object.



/**
* @class Ext.ux.form.field.DateTime
* @extends Ext.form.FieldContainer
* @version 0.2 (July 20th, 2011)
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
* @author ontho (http://www.sencha.com/forum/member.php?285806-ontho)
* @author jakob.ketterl (http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
* @link http://www.sencha.com/forum/showthread.php?134345-Ext.ux.form.field.DateTime
*/
Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',

//configurables

combineErrors: true,
msgTarget: 'under',
layout: 'hbox',
readOnly: false,

/**
* @cfg {String} dateFormat
* Convenience config for specifying the format of the date portion.
* This value is overridden if format is specified in the dateConfig.
* The default is 'Y-m-d'
*/
dateFormat: 'Y-m-d',
/**
* @cfg {String} timeFormat
* Convenience config for specifying the format of the time portion.
* This value is overridden if format is specified in the timeConfig.
* The default is 'H:i:s'
*/
timeFormat: 'H:i:s',
// /**
// * @cfg {String} dateTimeFormat
// * The format used when submitting the combined value.
// * Defaults to 'Y-m-d H:i:s'
// */
// dateTimeFormat: 'Y-m-d H:i:s',
/**
* @cfg {Object} dateConfig
* Additional config options for the date field.
*/
dateConfig:{},
/**
* @cfg {Object} timeConfig
* Additional config options for the time field.
*/
timeConfig:{},


// properties

dateValue: null, // Holds the actual date
/**
* @property dateField
* @type Ext.form.field.Date
*/
dateField: null,
/**
* @property timeField
* @type Ext.form.field.Time
*/
timeField: null,

initComponent: function(){
var me = this
,i = 0
,key
,tab;

me.items = me.items || [];

me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.dateConfig));
me.items.push(me.dateField);

me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.timeConfig));
me.items.push(me.timeField);

for (; i < me.items.length; i++) {
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
me.items[i].on('specialkey', function(field, event){
key = event.getKey();
tab = key == event.TAB;

if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}

me.fireEvent('specialkey', field, event);
});
}

me.callParent();

// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom:{},
swallowEvent:function(){}
};

me.initField();
},

focus:function(){
this.callParent();
this.dateField.focus();
},

onItemFocus:function(item){
if (this.blurTask){
this.blurTask.cancel();
}
this.focussedItem = item;
},

onItemBlur:function(item){
var me = this;
if (item != me.focussedItem){ return; }
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me);
});
me.blurTask.delay(100);
},

getValue: function(){
var value = null
,date = this.dateField.getSubmitValue()
,time = this.timeField.getSubmitValue()
,format;

if (date){
if (time){
format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
} else {
value = this.dateField.getValue();
}
}
return value;
},

getSubmitValue: function(){
// var value = this.getValue();
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;

var me = this
,format = me.getFormat()
,value = me.getValue();

return value ? Ext.Date.format(value, format) : null;
},

setValue: function(value){
if (Ext.isString(value)){
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
}
this.dateField.setValue(value);
this.timeField.setValue(value);
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
},

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this
,data = null;

if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});

//eo file

espeak
30 Jan 2012, 1:21 PM
This works great, however isValid() seems to be missing (or I am using it wrong). This fixed it for me:


isValid: function() {
return this.dateField.isValid() && this.timeField.isValid();
}

tayfun.ozis.erikan
21 Feb 2012, 2:56 AM
Minor addition for me.



//LINE 55:
allowBlank: true,




//...
me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
margin: '0 5 0 0',
allowBlank: me.allowBlank, // set as Default false
isFormField:false, //exclude from field query's
submitValue:false
}, me.dateConfig));
//...
me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
allowBlank: me.allowBlank, // set as Default false
isFormField:false, //exclude from field query's
submitValue:false
}, me.timeConfig));

TomJones
13 Jul 2012, 3:08 AM
I added this to my code and getting these errors:


giving me this error, when clicking on date cell:



Uncaught TypeError: Object #<Object> has no method 'removeAttribute' ext-all-debug.js:70898
Ext.define.beginLayoutShrinkWrap ext-all-debug.js:70898
Ext.define.beginLayout ext-all-debug.js:70861
Base.implement.callParent ext-all-debug.js:3732
Ext.define.beginLayout ext-all-debug.js:72183
Ext.define.resetLayout ext-all-debug.js:56620
Ext.define.invalidate ext-all-debug.js:56362
Ext.define.invalidate ext-all-debug.js:56350
Ext.define.flushInvalidates ext-all-debug.js:56204
Ext.define.run ext-all-debug.js:56670
Ext.define.statics.flushLayouts ext-all-debug.js:44984
Ext.define.statics.updateLayout ext-all-debug.js:45015
Ext.define.updateLayout ext-all-debug.js:46626
Ext.define.onShow ext-all-debug.js:45425
Base.implement.callParent ext-all-debug.js:3732
Ext.define.onShow ext-all-debug.js:58013
Base.implement.callParent ext-all-debug.js:3732
Ext.define.onShow ext-all-debug.js:78098
Base.implement.callParent ext-all-debug.js:3732
Ext.define.onShow ext-all-debug.js:78223
Ext.define.show ext-all-debug.js:57993
Ext.define.startEdit ext-all-debug.js:78031
call ext-all-debug.js:8423




and when deselecting cell, getting this :



Uncaught TypeError: Object #<Object> has no method 'getTarget' ext-all-debug.js:78142
Ext.define.onFieldBlur ext-all-debug.js:78142
call ext-all-debug.js:8423


This is how I apply it on my column:


{
xtype : 'enddatecolumn',
format: 'd/m/Y G:i',
width: 150,
align : 'center',

field : {
xtype : 'xdatetime'
}
}

TomJones
13 Jul 2012, 4:54 AM
ok I removed some lines from ext-all-debug.js and it gave me no errors.
Now the problem is that, when I edit the date, and press ENTER, date changes.

But when I edit the time, and press enter, it pops back to its original value. How can i fix this?


unimportant lines I removed, i guess they are useless:



/* if (e && Ext.fly(target = e.getTarget()).focusable()) {
target.focus();
} */



// inputEl.dom.removeAttribute('size');

mankz
29 Jul 2012, 10:31 PM
This works quite well for me:


/**
* @class Ext.ux.form.field.DateTime
* @extends Ext.form.FieldContainer
* @version 0.2 (July 20th, 2011)
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
* @author ontho (http://www.sencha.com/forum/member.php?285806-ontho)
* @author jakob.ketterl (http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
* @link http://www.sencha.com/forum/showthread.php?134345-Ext.ux.form.field.DateTime
*/
Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',

//configurables

combineErrors: true,
msgTarget: 'under',
layout: 'hbox',
readOnly: false,

/**
* @cfg {String} dateFormat
* Convenience config for specifying the format of the date portion.
* This value is overridden if format is specified in the dateConfig.
* The default is 'Y-m-d'
*/
dateFormat: 'Y-m-d',
/**
* @cfg {String} timeFormat
* Convenience config for specifying the format of the time portion.
* This value is overridden if format is specified in the timeConfig.
* The default is 'H:i:s'
*/
timeFormat: 'H:i:s',
// /**
// * @cfg {String} dateTimeFormat
// * The format used when submitting the combined value.
// * Defaults to 'Y-m-d H:i:s'
// */
// dateTimeFormat: 'Y-m-d H:i:s',
/**
* @cfg {Object} dateConfig
* Additional config options for the date field.
*/
dateConfig:{},
/**
* @cfg {Object} timeConfig
* Additional config options for the time field.
*/
timeConfig:{},


// properties

dateValue: null, // Holds the actual date
/**
* @property dateField
* @type Ext.form.field.Date
*/
dateField: null,
/**
* @property timeField
* @type Ext.form.field.Time
*/
timeField: null,

initComponent: function(){
var me = this
,i = 0
,key
,tab;

me.items = me.items || [];

me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.dateConfig));
me.items.push(me.dateField);

me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.timeConfig));
me.items.push(me.timeField);

for (; i < me.items.length; i++) {
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
me.items[i].on('specialkey', function(field, event){
key = event.getKey();
tab = key == event.TAB;

if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}

me.fireEvent('specialkey', field, event);
});
}

me.callParent();

// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom: document.createElement('div'),
swallowEvent:function(){}
};

me.initField();
},

focus:function(){
this.callParent(arguments);
this.dateField.focus();
},

onItemFocus:function(item){
if (this.blurTask){
this.blurTask.cancel();
}
this.focussedItem = item;
},

onItemBlur:function(item, e){
var me = this;
if (item != me.focussedItem){ return; }
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me, e);
});
me.blurTask.delay(100);
},

getValue: function(){
var value = null
,date = this.dateField.getSubmitValue()
,time = this.timeField.getSubmitValue()
,format;

if (date){
if (time){
format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
} else {
value = this.dateField.getValue();
}
}
return value;
},

getSubmitValue: function(){
// var value = this.getValue();
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;

var me = this
,format = me.getFormat()
,value = me.getValue();

return value ? Ext.Date.format(value, format) : null;
},

setValue: function(value){
if (Ext.isString(value)){
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
}
this.dateField.setValue(value);
this.timeField.setValue(value);
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
},

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this
,data = null;

if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});

//eo file

zhengeili
28 Aug 2012, 8:45 PM
\:D/国人的 哈哈

Jad
30 Aug 2012, 4:01 AM
Hi mankz

I use your code with Ext.grid.plugin.CellEditing and the editor is closed immediately after it's opened.

anny idea to fix it ?

grid column code


{
text: module.getLocale().translate(me.$className, 'departureDate', 'Departure Date'),
format: Ext.Date.patterns.ShortDate,
flex: 1,
dataIndex: 'departureDate',
itemId: 'departureDate',
renderer: function(value) {
try { return value ? Ext.Date.format(value, Ext.Date.patterns.DateTime) : ''; }
catch (ex) {}
},
editor: { xtype: 'xdatetime' }
},

danderson
26 Oct 2012, 9:15 AM
@zombeerose what is the rationale behind commenting out the dateTimeFormat option? Unless i'm missing something, this would make it quite the chore to submit the field as an epoch

zombeerose
26 Oct 2012, 10:24 AM
@danderson

Interesting point. I don't use epoch formatting so never considered the case. I had initially removed it because it appeared redundant to dateFormat + timeFormat.

I basically re-added the option in the same context as before but I don't specify a default value. IF you specify dateTimeFormat, it will take precedence over the separate formats. See if this works for you.



/**
* @class Ext.ux.form.field.DateTime
* @extends Ext.form.FieldContainer
* @version 0.3 (October 26th, 2012)
* @author [atian25](http://www.sencha.com/forum/member.php?51682-atian25)
* @author [ontho](http://www.sencha.com/forum/member.php?285806-ontho)
* @author [jakob.ketterl](http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
* [Forum Thread](http://www.sencha.com/forum/showthread.php?134345-Ext.ux.form.field.DateTime)
*/
Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',

//configurables

combineErrors: true,
msgTarget: 'under',
layout: 'hbox',
readOnly: false,

/**
* @cfg {String} dateFormat
* Convenience config for specifying the format of the date portion.
* This value is overridden if format is specified in the dateConfig.
* The default is 'Y-m-d'
*/
dateFormat: 'Y-m-d',

/**
* @cfg {String} dateTimeFormat
* An optional format used in place of {@link #dateFormat} and {@link timeFormat} to
* allow support for combined formatting, such as enoch, when calling
* {@link #getSubmitValue} and {@link setValue}.
*/

/**
* @cfg {String} timeFormat
* Convenience config for specifying the format of the time portion.
* This value is overridden if format is specified in the timeConfig.
* The default is 'H:i:s'
*/
timeFormat: 'H:i:s',
/**
* @cfg {Object} dateConfig
* Additional config options for the date field.
*/
dateConfig:{},
/**
* @cfg {Object} timeConfig
* Additional config options for the time field.
*/
timeConfig:{},



// properties

dateValue: null, // Holds the actual date
/**
* @property dateField
* @type Ext.form.field.Date
*/
dateField: null,
/**
* @property timeField
* @type Ext.form.field.Time
*/
timeField: null,


initComponent: function(){
var me = this,
i = 0,
key,
tab;

me.items = me.items || [];

me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.dateConfig));
me.items.push(me.dateField);

me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
format:me.timeFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false
}, me.timeConfig));
me.items.push(me.timeField);

for (; i < me.items.length; i++) {
me.items[i].on('focus', me.onItemFocus, me);
me.items[i].on('blur', me.onItemBlur, me);
me.items[i].on('select', me.onItemSelect, me);
me.items[i].on('specialkey', function(field, event){
key = event.getKey();
tab = key == event.TAB;

if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}

me.fireEvent('specialkey', field, event);
});
}


me.callParent();

// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom:{},
swallowEvent:function(){}
};

me.initField();
},

focus:function(){
this.callParent();
this.dateField.focus();
},

onItemFocus:function(item){
if (this.blurTask){
this.blurTask.cancel();
}
this.focussedItem = item;
},

onItemBlur:function(item){
var me = this;
if (item != me.focussedItem){ return; }
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me);
});
me.blurTask.delay(100);
},

/**
* @private Handles focus event
*/
onItemSelect:function() {
this.fireEvent("select", this);
},

getValue: function(){
var value = null,
date = this.dateField.getSubmitValue(),
time = this.timeField.getSubmitValue(),
format;


if (date){
if (time){
format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
} else {
value = this.dateField.getValue();
}
}
return value;
},

getSubmitValue: function(){
var me = this,
format = me.dateTimeFormat || me.getFormat(),
value = me.getValue();

return value ? Ext.Date.format(value, format) : null;
},

setValue: function(value){
var format;

if (Ext.isString(value)){
format = this.dateTimeFormat || this.getFormat();
value = Ext.Date.parse(value, format); //this.dateTimeFormat
}
this.dateField.setValue(value);
this.timeField.setValue(value);
},

getFormat: function(){
var df = this.dateField,
tf = this.timeField;
return ((df.submitFormat || df.format) + " " + (tf.submitFormat || tf.format));
},

// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this,
data = null;

if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});


//eo file

caodegao
27 Oct 2012, 6:19 AM
good!china

danderson
31 Oct 2012, 10:22 AM
@zombeerose

so far so good!

JacobGu
5 Nov 2012, 2:01 PM
This method needs to be added:


resetOriginalValue: function () {
this.dateField.resetOriginalValue();
this.timeField.resetOriginalValue();
}

zombeerose
6 Nov 2012, 10:32 AM
@JacobGu
I have added the resetOriginalValue method. I have also posted the code on github to make future contributions easier.

https://github.com/zombeerose/DateTime

(https://github.com/zombeerose/DateTime)NOTE: I refactored the code a bit because the previous implementation was creating a dummy inputEl, which was creating various problems (didn't work in 4.1.3). I have since reworked it using the Ext.calendar.form.field.DateRange example field as a model. Hopefully will be more in line with Sencha's best practices.

JacobGu
7 Nov 2012, 9:55 AM
Thanks.

I think it also needs:


onFieldDirtyChange: function () {
this.checkDirty();
}

and the following listener in both the date and time field objects:


'dirtychange': function () {
me.onFieldDirtyChange();
}

predator
2 Dec 2012, 2:48 PM
Hi,

form.loadRecord(record);

Does not load the field.

console.log(value); in setValue(value);

shows as undefined.

It works great when used as grid editor for a field, but in a plain form cannot load its value.

/A

Jangla
22 Feb 2013, 1:24 PM
I get this error on the line that creates the time field (seems to be related to attempting to use loadRecord into the field from a data store...perhaps?):

Cannot call method 'on' of undefined

seek
4 Apr 2013, 12:45 AM
Hi all, and thanks for this plugin!
All works perfectly, but there is a little problem when I leave the cell grid after editing: I must do a double click to another line in the grid, in order to confirm data (and get rid of pickers).
I'm using ExtJS 4.1.1a

42895

Any suggestion?
Thanks
Seek

Jojo79
9 May 2013, 2:41 AM
@atian25 - Thank you for the code. =D>

I have extended the code to include a hidden field so that date time value get submitted as a form field.



/**
* @class Ext.ux.form.field.DateTime
* @extends Ext.form.FieldContainer
*
* DateTime field, combination of DateField and TimeField
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
* @author Jojo79 (http://www.sencha.com/forum/member.php?321626-Jojo79)
*/
Ext.ns('Ext.ux.form');

Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins: {
field: 'Ext.form.field.Field'
},
alias: ['widget.xdatetime'],
layout: {
type: 'hbox',
align: 'stretch'
},

dateFormat:'m/d/y',
timeFormat:'g:i A',

height: 22,
style: {
width : "100%"
},
dateCfg:{},
timeCfg:{},
valueCfg:{},

initComponent: function() {
var me = this;
me.buildField();
me.callParent();
this.dateField = this.down('datefield');
this.timeField = this.down('timefield');
this.valueField = this.down('hiddenfield');
me.initField();
},

//@private
buildField: function(){
this.items = [
Ext.apply({
xtype: 'datefield',
id: this.id + "-date",
name : this.name + "-date",
format: this.dateFormat || Ext.form.DateField.prototype.format,
flex: .55,
margin: '0 1 0 0',
submitValue: false,
listeners : {
'change':function ( dateObj, newValue, oldValue, eOpts ){
this.ownerCt.onUpdateDate();
}
}
},this.dateCfg),
Ext.apply({
xtype: 'timefield',
id: this.id + "-time",
name : this.name + "-time",
format: this.timeFormat || Ext.form.TimeField.prototype.format,
flex: .45,
margin: '0 0 0 1',
submitValue: false,
listeners : {
'change':function ( dateObj, newValue, oldValue, eOpts ){
this.ownerCt.onUpdateTime();
}
}
},this.timeCfg),
Ext.apply({
xtype: 'hiddenfield',
id: this.id + "-datetimevalue",
name: this.name + "-datetimevalue",
value: '',
getValue: function(){
if(this.ownerCt) {
return this.ownerCt.getValue();
}else{
return;
}
},
getSubmitData: function(){
data = {};
if(this.ownerCt){
data[this.ownerCt.name] = '' + this.ownerCt.getRawValue()
}
return data;
}
}, this.valueCfg)
]
},

getValue: function() {
var value = '',date = this.dateField.getSubmitValue(),time = this.timeField.getSubmitValue();
if(date){
if(time){
var format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time,format);
}else{
value = this.dateField.getValue();
}
}
return value;
},

setValue: function(value){
this.dateField.setValue(value);
this.timeField.setValue(value);
this.valueField.value = this.getRawValue();
},

getSubmitData: function(){
data = {};
return data[this.name] = '' + this.getRawValue();
},

getFormat: function(){
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format)
},

getRawValue: function() {
if(this.getValue()){
return '' + this.getValue().getTime();
}
return '';
},

getTime: function() {
if(!Ext.isEmpty(this.getValue())){
return this.getValue().getTime();
}
},

initDateValue:function() {
return new Date();
},

onUpdateDate:function() {
var d = this.dateField.getValue();
if(!d){
this.timeField.setValue('');
}
if(d && !(d instanceof Date)) {
d = Ext.Date.parse(d, this.dateField.format);
}
if(d && !this.timeField.getValue()) {
this.timeField.setValue(this.initDateValue());
}
this.valueField.value = this.getRawValue();
},

onUpdateTime:function() {
var t = this.timeField.getValue();
if(t && !(t instanceof Date)) {
t = Ext.Date.parse(t, this.timeField.format);
}
if(t && !this.dateField.getValue()) {
this.dateField.setValue(this.initDateValue());
}
this.valueField.value = this.getRawValue();
}

})


Thanks!