PDA

View Full Version : [new version] DateTime Field



Pages : [1] 2 3 4

jsakalos
9 Jan 2008, 3:06 PM
EDIT: due to the limitations of the first version that I've posted here originally I've completely re-written the DateTime field. This is new code:



<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css">
<script type="text/javascript" src="../ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext/ext-all-debug.js"></script>
<script type="text/javascript">

// vim: ts=4:sw=4:nu:fdc=4:nospell
/*global Ext */
/**
* @class Ext.ux.form.DateTime
* @extends Ext.form.Field
*
* DateTime field, combination of DateField and TimeField
*
* @author Ing. Jozef Sakáloš
* @copyright (c) 2008, Ing. Jozef Sakáloš
* @version 2.0
* @revision $Id: Ext.ux.form.DateTime.js 813 2010-01-29 23:32:36Z jozo $
*
* @license Ext.ux.form.DateTime is licensed under the terms of
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
* that the code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
* target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
*
* @forum 22661
*
* @donate
* <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
* <input type="hidden" name="cmd" value="_s-xclick">
* <input type="hidden" name="hosted_button_id" value="3430419">
* <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif"
* border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
* <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
* </form>
*/

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

/**
* Creates new DateTime
* @constructor
* @param {Object} config A config object
*/
Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
/**
* @cfg {Function} dateValidator A custom validation function to be called during date field
* validation (defaults to null)
*/
dateValidator:null
/**
* @cfg {String/Object} defaultAutoCreate DomHelper element spec
* Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
*/
,defaultAutoCreate:{tag:'input', type:'hidden'}
/**
* @cfg {String} dtSeparator Date - Time separator. Used to split date and time (defaults to ' ' (space))
*/
,dtSeparator:' '
/**
* @cfg {String} hiddenFormat Format of datetime used to store value in hidden field
* and submitted to server (defaults to 'Y-m-d H:i:s' that is mysql format)
*/
,hiddenFormat:'Y-m-d H:i:s'
/**
* @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
*/
,otherToNow:true
/**
* @cfg {Boolean} emptyToNow Set field value to now on attempt to set empty value.
* If it is true then setValue() sets value of field to current date and time (defaults to false)
*/
/**
* @cfg {String} timePosition Where the time field should be rendered. 'right' is suitable for forms
* and 'below' is suitable if the field is used as the grid editor (defaults to 'right')
*/
,timePosition:'right' // valid values:'below', 'right'
/**
* @cfg {Function} timeValidator A custom validation function to be called during time field
* validation (defaults to null)
*/
,timeValidator:null
/**
* @cfg {Number} timeWidth Width of time field in pixels (defaults to 100)
*/
,timeWidth:100
/**
* @cfg {String} dateFormat Format of DateField. Can be localized. (defaults to 'm/y/d')
*/
,dateFormat:'m/d/y'
/**
* @cfg {String} timeFormat Format of TimeField. Can be localized. (defaults to 'g:i A')
*/
,timeFormat:'g:i A'
/**
* @cfg {Object} dateConfig Config for DateField constructor.
*/
/**
* @cfg {Object} timeConfig Config for TimeField constructor.
*/

// {{{
/**
* @private
* creates DateField and TimeField and installs the necessary event handlers
*/
,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 || Ext.form.DateField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,validator:this.dateValidator
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
}
}, this.dateConfig);
this.df = new Ext.form.DateField(dateConfig);
this.df.ownerCt = this;
delete(this.dateFormat);

// create TimeField
var timeConfig = Ext.apply({}, {
id:this.id + '-time'
,format:this.timeFormat || Ext.form.TimeField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,validator:this.timeValidator
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
}
}, this.timeConfig);
this.tf = new Ext.form.TimeField(timeConfig);
this.tf.ownerCt = this;
delete(this.timeFormat);

// relay events
this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);

this.on('specialkey', this.onSpecialKey, this);

} // eo function initComponent
// }}}
// {{{
/**
* @private
* Renders underlying DateField and TimeField and provides a workaround for side error icon bug
*/
,onRender:function(ct, position) {
// don't run more than once
if(this.isRendered) {
return;
}

// render underlying hidden field
Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);

// render DateField and TimeField
// create bounding table
var t;
if('below' === this.timePosition || 'bellow' === this.timePosition) {
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 {
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 = t.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'));

// workaround for IE trigger misalignment bug
// see http://extjs.com/forum/showthread.php?p=341075#post341075
// if(Ext.isIE && Ext.isStrict) {
// t.select('input').applyStyles({top:0});
// }

this.df.el.swallowEvent(['keydown', 'keypress']);
this.tf.el.swallowEvent(['keydown', 'keypress']);

// create icon for side invalid errorIcon
if('side' === this.msgTarget) {
var elp = this.el.findParent('.x-form-element', 10, true);
if(elp) {
this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
}

var o = {
errorIcon:this.errorIcon
,msgTarget:'side'
,alignErrorIcon:this.alignErrorIcon.createDelegate(this)
};
Ext.apply(this.df, o);
Ext.apply(this.tf, o);
// this.df.errorIcon = this.errorIcon;
// this.tf.errorIcon = this.errorIcon;
}

// setup name for submit
this.el.dom.name = this.hiddenName || this.name || this.id;

// prevent helper fields from being submitted
this.df.el.dom.removeAttribute("name");
this.tf.el.dom.removeAttribute("name");

// we're rendered flag
this.isRendered = true;

// update hidden field
this.updateHidden();

} // eo function onRender
// }}}
// {{{
/**
* @private
*/
,adjustSize:Ext.BoxComponent.prototype.adjustSize
// }}}
// {{{
/**
* @private
*/
,alignErrorIcon:function() {
this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
}
// }}}
// {{{
/**
* @private initializes internal dateValue
*/
,initDateValue:function() {
this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
}
// }}}
// {{{
/**
* Calls clearInvalid on the DateField and TimeField
*/
,clearInvalid:function(){
this.df.clearInvalid();
this.tf.clearInvalid();
} // eo function clearInvalid
// }}}
// {{{
/**
* Calls markInvalid on both DateField and TimeField
* @param {String} msg Invalid message to display
*/
,markInvalid:function(msg){
this.df.markInvalid(msg);
this.tf.markInvalid(msg);
} // eo function markInvalid
// }}}
// {{{
/**
* @private
* called from Component::destroy.
* Destroys all elements and removes all listeners we've created.
*/
,beforeDestroy:function() {
if(this.isRendered) {
// this.removeAllListeners();
this.wrap.removeAllListeners();
this.wrap.remove();
this.tableEl.remove();
this.df.destroy();
this.tf.destroy();
}
} // eo function beforeDestroy
// }}}
// {{{
/**
* Disable this component.
* @return {Ext.Component} this
*/
,disable:function() {
if(this.isRendered) {
this.df.disabled = this.disabled;
this.df.onDisable();
this.tf.onDisable();
}
this.disabled = true;
this.df.disabled = true;
this.tf.disabled = true;
this.fireEvent("disable", this);
return this;
} // eo function disable
// }}}
// {{{
/**
* Enable this component.
* @return {Ext.Component} this
*/
,enable:function() {
if(this.rendered){
this.df.onEnable();
this.tf.onEnable();
}
this.disabled = false;
this.df.disabled = false;
this.tf.disabled = false;
this.fireEvent("enable", this);
return this;
} // eo function enable
// }}}
// {{{
/**
* @private Focus date filed
*/
,focus:function() {
this.df.focus();
} // eo function focus
// }}}
// {{{
/**
* @private
*/
,getPositionEl:function() {
return this.wrap;
}
// }}}
// {{{
/**
* @private
*/
,getResizeEl:function() {
return this.wrap;
}
// }}}
// {{{
/**
* @return {Date/String} Returns value of this field
*/
,getValue:function() {
// create new instance of date
return this.dateValue ? new Date(this.dateValue) : '';
} // eo function getValue
// }}}
// {{{
/**
* @return {Boolean} true = valid, false = invalid
* @private Calls isValid methods of underlying DateField and TimeField and returns the result
*/
,isValid:function() {
return this.df.isValid() && this.tf.isValid();
} // eo function isValid
// }}}
// {{{
/**
* Returns true if this component is visible
* @return {boolean}
*/
,isVisible : function(){
return this.df.rendered && this.df.getActionEl().isVisible();
} // eo function isVisible
// }}}
// {{{
/**
* @private Handles blur event
*/
,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();

this.validate();

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

} // eo function onBlur
// }}}
// {{{
/**
* @private Handles focus event
*/
,onFocus:function() {
if(!this.hasFocus){
this.hasFocus = true;
this.startValue = this.getValue();
this.fireEvent("focus", this);
}
}
// }}}
// {{{
/**
* @private Just to prevent blur event when clicked in the middle of fields
*/
,onMouseDown:function(e) {
if(!this.disabled) {
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
}
}
// }}}
// {{{
/**
* @private
* Handles Tab and Shift-Tab events
*/
,onSpecialKey:function(t, e) {
var key = e.getKey();
if(key === e.TAB) {
if(t === this.df && !e.shiftKey) {
e.stopEvent();
this.tf.focus();
}
if(t === this.tf && e.shiftKey) {
e.stopEvent();
this.df.focus();
}
this.updateValue();
}
// otherwise it misbehaves in editor grid
if(key === e.ENTER) {
this.updateValue();
}

} // eo function onSpecialKey
// }}}
// {{{
/**
* Resets the current field value to the originally loaded value
* and clears any validation messages. See Ext.form.BasicForm.trackResetOnLoad
*/
,reset:function() {
this.df.setValue(this.originalValue);
this.tf.setValue(this.originalValue);
} // eo function reset
// }}}
// {{{
/**
* @private Sets the value of DateField
*/
,setDate:function(date) {
this.df.setValue(date);
} // eo function setDate
// }}}
// {{{
/**
* @private Sets the value of TimeField
*/
,setTime:function(date) {
this.tf.setValue(date);
} // eo function setTime
// }}}
// {{{
/**
* @private
* Sets correct sizes of underlying DateField and TimeField
* With workarounds for IE bugs
*/
,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);
}
}
} // eo function setSize
// }}}
// {{{
/**
* @param {Mixed} val Value to set
* Sets the value of this field
*/
,setValue:function(val) {
if(!val && true === this.emptyToNow) {
this.setValue(new Date());
return;
}
else if(!val) {
this.setDate('');
this.setTime('');
this.updateValue();
return;
}
if ('number' === typeof val) {
val = new Date(val);
}
else if('string' === typeof val && this.hiddenFormat) {
val = Date.parseDate(val, this.hiddenFormat);
}
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
var da;
if(val instanceof Date) {
this.setDate(val);
this.setTime(val);
this.dateValue = new Date(Ext.isIE ? val.getTime() : val);
}
else {
da = val.split(this.dtSeparator);
this.setDate(da[0]);
if(da[1]) {
if(da[2]) {
// add am/pm part back to time
da[1] += da[2];
}
this.setTime(da[1]);
}
}
this.updateValue();
} // eo function setValue
// }}}
// {{{
/**
* Hide or show this component by boolean
* @return {Ext.Component} this
*/
,setVisible: function(visible){
if(visible) {
this.df.show();
this.tf.show();
}else{
this.df.hide();
this.tf.hide();
}
return this;
} // eo function setVisible
// }}}
//{{{
,show:function() {
return this.setVisible(true);
} // eo function show
//}}}
//{{{
,hide:function() {
return this.setVisible(false);
} // eo function hide
//}}}
// {{{
/**
* @private Updates the date part
*/
,updateDate:function() {

var d = this.df.getValue();
if(d) {
if(!(this.dateValue instanceof Date)) {
this.initDateValue();
if(!this.tf.getValue()) {
this.setTime(this.dateValue);
}
}
this.dateValue.setMonth(0); // because of leap years
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth(), d.getDate());
// this.dateValue.setDate(d.getDate());
}
else {
this.dateValue = '';
this.setTime('');
}
} // eo function updateDate
// }}}
// {{{
/**
* @private
* Updates the time part
*/
,updateTime:function() {
var t = this.tf.getValue();
if(t && !(t instanceof Date)) {
t = Date.parseDate(t, this.tf.format);
}
if(t && !this.df.getValue()) {
this.initDateValue();
this.setDate(this.dateValue);
}
if(this.dateValue instanceof Date) {
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);
}
}
} // eo function updateTime
// }}}
// {{{
/**
* @private Updates the underlying hidden field value
*/
,updateHidden:function() {
if(this.isRendered) {
var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
this.el.dom.value = value;
}
}
// }}}
// {{{
/**
* @private Updates all of Date, Time and Hidden
*/
,updateValue:function() {

this.updateDate();
this.updateTime();
this.updateHidden();

return;
} // eo function updateValue
// }}}
// {{{
/**
* @return {Boolean} true = valid, false = invalid
* calls validate methods of DateField and TimeField
*/
,validate:function() {
return this.df.validate() && this.tf.validate();
} // eo function validate
// }}}
// {{{
/**
* Returns renderer suitable to render this field
* @param {Object} Column model config
*/
,renderer: function(field) {
var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
var renderer = function(val) {
var retval = Ext.util.Format.date(val, format);
return retval;
};
return renderer;
} // eo function renderer
// }}}

}); // eo extend

// register xtype
Ext.reg('xdatetime', Ext.ux.form.DateTime);

// eof

Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif';
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
var win = new Ext.Window({
width:500
,id:'winid'
,height:300
,layout:'fit'
,border:false
,closable:false
,title:'Ext.ux.form.DateTime Example'
,items:[{
xtype:'form'
,frame:true
,labelWidth:100
,id:'form'
,url:'.'
,items:[{
xtype:'xdatetime'
,id:'dtf'
,fieldLabel:'Date & Time'
// ,width:360
,anchor:'-18'
,timeFormat:'H:i:s'
,timeConfig: {
altFormats:'H:i:s'
,allowBlank:true
}
,dateFormat:'d.n.Y'
,dateConfig: {
altFormats:'Y-m-d|Y-n-d'
,allowBlank:true
}
}]
}]
,buttons:[{
text:'Submit'
,handler:function() {
Ext.getCmp('form').getForm().submit();
}
}]
});
win.show();
});
</script>
<title>Ext.ux.form.DateTime Example</title>
</head>
<body>
</body>
</html>
Original post:

Hi all,

inspired by this thread: http://extjs.com/forum/showthread.php?t=20902 and being in urgent necessity I've written DateTime field that supports anchoring and user definable formats. Here is the self contained code; give it a try please:

EDIT: old code deleted.

DigitalSkyline
9 Jan 2008, 3:13 PM
Is it the same as this?
Screenshot:

http://www.pobox.com/~berend/extjs/datetimefield_example.png

If so Awesome! Sorry no I haven't tried it yet but will be very useful I think.

jsakalos
9 Jan 2008, 3:33 PM
Basically yes, but the other version doesn't support anchoring and has only one fixed format for date and time.

jsakalos
9 Jan 2008, 3:36 PM
Snapshot:

cocorossello
10 Jan 2008, 4:47 AM
Awesome :D, Thx!

magunes117
10 Jan 2008, 5:39 AM
Thanks, its great. But it doesn't work in IE6 (or IE7).

jsakalos
10 Jan 2008, 9:24 AM
Thanks, its great. But it doesn't work in IE6 (or IE7).

Try it now; I've updated the code in the first post. Tested in IE7 - works.

wenner
10 Jan 2008, 6:10 PM
:(( doesn't work in IE6!!!

magunes117
10 Jan 2008, 11:41 PM
Try it now; I've updated the code in the first post. Tested in IE7 - works.

The window appears this time, but the fields are missing (both in IE6 & IE7).

jsakalos
11 Jan 2008, 3:49 AM
I found out that it doesn't work in IE quirks mode. I've added doctype to the code above and it works.

magunes117
11 Jan 2008, 5:14 AM
I found out that it doesn't work in IE quirks mode. I've added doctype to the code above and it works.

It is working in IE7 now, fields are still missing in IE6.

Thanks.

jsakalos
11 Jan 2008, 5:40 AM
I've changed rendering of date and time fields so now it should work in IE6/7 in quirks/strict modes flawlessly.

magunes117
11 Jan 2008, 5:57 AM
Now it works in FF2, IE6, IE7, Opera9. Thank you.

I need to disable the editing of 'seconds'. I want it to be '00' all the time, how can I do this? Edit: I have done it, thanks.

Regards.

jsakalos
11 Jan 2008, 6:48 AM
You have two variables dateFormat and timeFormat that are used for underlying fields. Then you have dateConfig and timeConfig objects that are applied to config objects of underlying fields as documented for DateField and TimeField of Ext.

Reason for moving format configs from underlying fields to DateTime object is that this way it is easy to localize date and time formats.

acontreras
11 Jan 2008, 12:13 PM
jsakalos, I can't get to validate the fields on the form.

I'm using allowBlank:false, but When I call a form.getForm().isValid(). it doesn't validates the empty fields.

Is it a bug, or it's just my mis configuration?

jsakalos
11 Jan 2008, 6:02 PM
I haven't done validation yet...

jsakalos
11 Jan 2008, 6:14 PM
jsakalos, I can't get to validate the fields on the form.

I'm using allowBlank:false, but When I call a form.getForm().isValid(). it doesn't validates the empty fields.

Is it a bug, or it's just my mis configuration?


It was easier that I'd thought. Get the code from the first post now and give it a try.

galdaka
12 Jan 2008, 12:24 AM
Good work!!

Thanks again jsakalos,

jsakalos
13 Jan 2008, 6:22 PM
I needed to use this field as grid editor so I had to solve all issues connected with that. I think the field plays very nicely when embedded in a grid, however, I have tested it only in Firefox@Linux.

Give it a try as grid editor and let me know issues, if any.

wenner
13 Jan 2008, 8:46 PM
I needed to use this field as grid editor so I had to solve all issues connected with that. I think the field plays very nicely when embedded in a grid, however, I have tested it only in Firefox@Linux.

Give it a try as grid editor and let me know issues, if any.

i try the code

Ext.getCmp('form').getForm().reset()

getValues is NaN , the field show "NaN.NaN.NaN"

jsakalos
14 Jan 2008, 3:37 AM
i try the code

Ext.getCmp('form').getForm().reset()getValues is NaN , the field show "NaN.NaN.NaN"

Thanks for bug report. It's fixed now.

wenner
14 Jan 2008, 4:16 AM
bug:
1. Focus the field but don't select , then click 'submit' , getvalue() is empty "" -- only IE
2. click 'submit' again , alert "NaN.NaN.NaN NaN:NaN:NaN" -- IE6 && FF2

and i use the new script of the top post.....

how fix?

acontreras
14 Jan 2008, 4:37 AM
It was easier that I'd thought. Get the code from the first post now and give it a try.


Nice, now it's validating.

Thanks! \:D/

daviscabral
14 Jan 2008, 5:44 AM
On focus/blur this happens:

elp has no properties
this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'}...

jsakalos
14 Jan 2008, 8:47 AM
On focus/blur this happens:

elp has no properties
this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'}...

Post your code. Never happened to me.

daviscabral
14 Jan 2008, 9:17 AM
Follow:

DadosVisita: function() {
var dialog = Ext.WindowMgr.getActive();
var dsProspectsTiposContatos = Ext.StoreMgr.get("dsProspectsTiposContatos");
if ( !dsProspectsTiposContatos ) {
var dsProspectsTiposContatos = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({url: "../ProspectsTiposContatos/Index.ashx"}),
reader: new Ext.data.JsonReader({root: 'Results',totalProperty: 'totalItems'}, [
{name: 'Id'},
{name: 'Descricao'}
])
});
dsProspectsTiposContatos.load({params: {sort:"Descricao",start:0,limit:9999,dir:"ASC",combobox: true}});
Ext.StoreMgr.add("dsProspectsTiposContatos", dsProspectsTiposContatos);
}
return {
id: dialog.id+'_Visitas',
title:'Dados da visita',
layout:'form',
labelWidth: 120,
bodyStyle:'padding:10px',
border:false,
closable:true,
items:[{
xtype: 'reloadcombobox',
fieldLabel:'Tipo',
hiddenName:'ProspectContato.ProspectTipoContato.Id',
store:dsProspectsTiposContatos,
valueField:'Id',
displayField:'Descricao',
forceSelection:true,
typeAhead:true,
mode:'local',
selectOnFocus:true,
width: '94%',
allowBlank:false
},{
xtype: 'xdatetime',
fieldLabel:'Data',
id:dialog.id+'_Data',
name:'ProspectContato.Data',
forceSelection:true,
typeAhead:true,
anchor:'94%',
timeFormat:'H:i:s',
timeConfig: {
altFormats:'H:i:s',
allowBlank:false
},
dateFormat:'d/m/Y',
dateConfig: {
altFormats:'Y-m-d|Y-n-d',
allowBlank:false
}
},{
xtype: 'textarea',
fieldLabel:'Resultado',
name:'ProspectContato.Resultado',
height: 160,
width: '90%',
allowBlank:false
}]
};
}


elp has no properties
markInvalid("Este campo &eacute; obrigat&oacute;rio.")ext-all.js (line 25362)
validateValue("")ext-all.js (line 25673)
validateValue("")ext-all.js (line 26173)
validate()ext-all.js (line 25319)
onBlur()ext-customization... (line 271)
triggerBlur()ext-all.js (line 25847)
mimicBlur(Object browserEvent=Event mousedown button=0)ext-all.js (line 25835)
h(Object browserEvent=Event mousedown button=0)ext-all.js (line 1629)
(no name)()ext-all.js (line 1592)
[Break on this error] this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'}...

The line red is here:

Ext.override(Ext.form.Field, {
// private
onBlur : function(){
this.el.removeClass(this.focusClass);
this.hasFocus = false;
if (this.forceUpperCase) {
this.el.dom.value = String(this.getValue()).toUpperCase();
}
if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
this.validate();
}
var v = this.getValue();
if(v != this.startValue){
this.fireEvent('change', this, v, this.startValue);
}
this.fireEvent("blur", this);
}
});

Thanks!

jsakalos
14 Jan 2008, 11:25 AM
Hmmm,

I don't have enough time to make your code runnable by putting it go a page. I meant a full runnable code that I can run, change and debug fast.

Nevertheless, for the first glance, you override onBlur method of Ext.form.Field so I cannot help in that case as the problem lies most likely in your override.

I use this field both in form and grid and it works flawlessly.

daviscabral
15 Jan 2008, 3:42 AM
I found the error:

Ext.form.Field.prototype.msgTarget = 'side';


case 'side':
if(!this.errorIcon){
var elp = this.el.findParent('.x-form-element', 5, true);
this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
}
this.alignErrorIcon();
this.errorIcon.dom.qtip = msg;
this.errorIcon.dom.qclass = 'x-form-invalid-tip';
this.errorIcon.show();
this.on('resize', this.alignErrorIcon, this);
break;

JorisA
16 Jan 2008, 8:26 AM
Great jsakalos :)
I know many people were asking for this and I will definitively find a place for it in my current application :)

linizou
16 Jan 2008, 9:53 PM
It work fine on IE 7 . thanks.

linizou
16 Jan 2008, 10:05 PM
It work fine on IE 7 . thanks.
ok

acontreras
17 Jan 2008, 4:28 AM
Works fine on IE7 :)

JorisA
17 Jan 2008, 4:45 AM
Wouldn't it be easier to just use a datefield then?

Edit:
Hmm I'm pretty sure this was a reply on "How can I hide the time field" or something, but I must have been high on crack or so cause I can't find it anymore. New time I better quote :P

rlx
17 Jan 2008, 11:25 AM
i tried to use the extension in my form but keep getting an exception on setvalue, if the element is not yet rendered (updatevalue tries to access the dom, which does not exist yet). is there any workaround for that?



this.dtGoodAfterTime = new Ext.ux.form.DateTime(
{
fieldLabel: _('Good After'),
name: 'goodaftertime',
id: 'goodaftertime',
width: 165,
timeFormat:'H:i:s',
timeConfig:
{
altFormats:'H:i:s',
allowBlank: false
},
dateFormat:'m/d/y',
dateConfig:
{
altFormats:'Y-m-d',
allowBlank: false
}
});
this.dtGoodAfterTime.setValue(new Date());

jsakalos
17 Jan 2008, 2:49 PM
Wouldn't it be easier to just use a datefield then?

Hmmm, I must admit that I understand individual words but not the whole concept...:-/

jsakalos
17 Jan 2008, 2:51 PM
i tried to use the extension in my form but keep getting an exception on setvalue, if the element is not yet rendered (updatevalue tries to access the dom, which does not exist yet). is there any workaround for that?

What standard Ext form fields do when you try to setValue before rendered?

jsakalos
17 Jan 2008, 2:53 PM
Ok, I see it now. They test if component is rendered and access dom only if yes. I'll fix it soon.

jsakalos
17 Jan 2008, 3:15 PM
rlx, try it now - I've updated it but I haven't tried to call setValue() before rendered. Hopefully it works now.

wenner
17 Jan 2008, 7:38 PM
bug:
1. Focus the field but don't select , then click 'submit' , getvalue() is empty "" -- only IE
2. click 'submit' again , alert "NaN.NaN.NaN NaN:NaN:NaN" -- IE6 && FF2

and i use the new script of the top post.....

how fix?

...sorry for my english .. can help?

chernomorez
21 Jan 2008, 8:57 AM
I have extracted the javascript code into a separate file, but whenever I create the object, I am getting "Ext.ux.form.DateTime is not a Constructor" error message in firebug.

here's my code:


var dateField = new Ext.ux.form.DateTime({
fieldLabel:'my Label',
width:175,
id: 'myID'
});


Any clues?

jsakalos
21 Jan 2008, 11:07 AM
You need to include this file in head of your main page. Use Firebug to see if this file is found - Scripts tab of Firebug, select that file and you have to see its content.

trancee
24 Jan 2008, 5:15 AM
Great extension!
Just one note: shouldn't it be dateWidth instead of timeWidth for the date field?

jsakalos
24 Jan 2008, 5:35 AM
Great extension!
Just one note: shouldn't it be dateWidth instead of timeWidth for the date field?

Well, it's matter of taste; you can change it if you want.

ajaxE
26 Jan 2008, 10:35 PM
I am getting JS error by adding a transformed combo on top of this.


var comboConfig = Ext.apply({}, {
id: this.id + '-combo'
, typeAhead: true
, triggerAction: 'all'
, transform: 'state'
, width:135
, editable: false
, forceSelection:true
,lazyRender: true
, fieldLabel:'State'}, this.comboConfig);
this.cb = new Ext.form.ComboBox(comboConfig);

Any help is appreciated!
Thanks

jsakalos
27 Jan 2008, 9:21 AM
I have no clue what point are you trying to make... Wrong thread?

ajaxE
27 Jan 2008, 1:59 PM
No, this is the correct thread.

I was tried to add a transformed combo on the top of your extension. I always get a JS error if I included "lazyRender:true".

For your extension, I need to do things differently to include transformed combo into the form?

Thanks

jsakalos
27 Jan 2008, 2:13 PM
Hmmm, I still don't get what means "add a transformed combo on the top of your extension".

DateTime field uses two fields internally DateField and TimeField.

Can you post some code?

ajaxE
27 Jan 2008, 2:22 PM
Thanks for your quick reply.

I want to add a transformed combo into your extension. The HTML code is as below:


<html>
<head>
.....
</head>
<body>
<select name="state" id="state">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
</select>
</body>
</html>

The JS code is all your JS with addition of following:


var comboConfig = Ext.apply({}, {
id: this.id + '-combo'
, typeAhead: true
, triggerAction: 'all'
, transform: 'state'
, width:135
, editable: false
, forceSelection:true
, fieldLabel:'State'}, this.comboConfig);
this.cb = new Ext.form.ComboBox(comboConfig);

If I added "lazyRender: true", the combo is showing in the form along with date & time. But it produces the JS error. If I take out the "lazyRender: true". The combo is showing outside the form.

Thanks!

jsakalos
27 Jan 2008, 2:54 PM
Well, this is DateTime extension and it has nothing to do with standard combos. If you just need to transform markup to Ext.ComboBox you do not need this extension.

umlbuzzard
29 Jan 2008, 10:40 AM
Thanks for bug report. It's fixed now.

I am still seeing this problem grabbing the code from your initial post. Am I missing something?

Thanks

jsakalos
29 Jan 2008, 11:04 AM
I've completely re-written the DateTime field. See the first post.

miles.huang
29 Jan 2008, 12:35 PM
I found 2 additional parameters in the http POST message for each DateTime Field. Obviously these are underling date field and time field. Although this will not cause big problems :)

jsakalos
29 Jan 2008, 12:42 PM
Yes, you're right. They are:

<datatimename>-date and <datetimename>-time.

I've just ignored that these extra values are posted - server can ignore 'em too. ;)

sharman
30 Jan 2008, 2:16 PM
I could be wrong, but there seems to be an issue when using a msgTarget of 'side'. I know this issue existed with the previous version and now with the current version. Using FF2.0 and IE6.0 for testing. I have been trying to fix it myself so I could help instead of just reporting the issue. Using your orginal example, if you just add the line below the init(), it can be easily reproduced.

Ext.onReady(function() {
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
var win = new Ext.Window({

I was hoping to provide a fix for this issue rather then reporting it. As close as I am getting I keep breaking something else. This extension is one of my favorites to date.

jsakalos
30 Jan 2008, 2:57 PM
Sharman,

thanks for pointing out. It's now fixed; grab the code from the first post.

sinma
31 Jan 2008, 12:58 AM
Jozef, thanks a lot for this great extension!

marco76
4 Feb 2008, 5:41 AM
Hi
I use the Ext.ux.form.DateTime Extension.
In FF it works perfectly instead in IE6 and IE7 it doesn't work.
I have a tabpanel with two formpanel.
In the first panel (that is the activatePanel) I use the datetime field.
Now at the Beginning I can't see the datetime field.
If I select the other panel and then reselect the first panel then I can see the datetime field
What is the problem?
Marco

jsakalos
4 Feb 2008, 6:11 AM
Try deferredRender:false on tab panel and if it doesn't help post a showcase that I can debug locally.

marco76
4 Feb 2008, 6:41 AM
I post my code:
I create my class:



DocumentForm = function() {





DocumentForm.superclass.constructor.call(this, {
labelWidth: 75,
method:'POST',
closable:true,
border:true,
title: 'PROVA',
defaultType: 'textfield',
items: [

{ xtype:'tabpanel', plain:true, autoScroll:true, activeTab: 0, height:500, defaults:{bodyStyle:'padding:10px'}, items:[{ title:'Dati', cls:'x-plain', layout:'form', autoScroll:true, defaultType: 'textfield', items:[new Ext.ux.form.DateTime({ fieldLabel: 'Data Inizio', name:'data[InformazioneCampo][3]', value:'31/01/2008 07:30', allowBlank:false, readOnly:true, timeFormat:'H:i', timeConfig: { altFormats:'H:i', allowBlank:false, value: '07:30', readOnly:true }, dateFormat:'d/m/Y', dateConfig: { altFormats:'Y-m-d|Y-n-d', allowBlank:false, value: '31/01/2008', readOnly:true } })] },{ cls:'x-plain', title:'Destinatari', autoScroll:true, layout:'fit' }] }

]

});

};

Ext.extend(DocumentForm, Ext.form.FormPanel, {}




});

jsakalos
4 Feb 2008, 7:23 AM
Hmmm,

that is very unusual way of extending class. How and when do you run it then? Post please the complete html that I can copy to examples directory and run here.

MaximGB
10 Feb 2008, 4:35 AM
Hi.
Useful extension thanks ;).
I use xdatetime field this anchor: [-20] and the side error icon is positioned incorrectly (see the image). I've modified the extension code with following patches to solve the issue:


,alignErrorIcon:function() {
this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
}
...
,setSize:function(w, h) {
...
if (this.errorIcon) {
this.alignErrorIcon();
}
}

jsakalos
10 Feb 2008, 5:59 AM
Thank you for debugging, I'm incorporating your patch.

Cheers,

grEvenX
13 Feb 2008, 6:13 AM
Excellent Ext.ux :) I would very much like to see this as a standard feature in the Ext framework!

jsakalos
18 Feb 2008, 6:18 PM
Hi all!

I've doced the extension, fixed small bugs (in-grid enter key behavior), and incorporated some improvements (time field position, renderer function for grids).

Any ideas/bugs before I post it to Learn Section?

Cheers,

Egor
19 Feb 2008, 6:35 PM
Jozef you're a legend! Thanks so much for making this.

One thing I discovered is that disable() and enable() didn't work on the xdatetime field. I just added the following to its methods and it seems to work.



,disable:function() {
this.df.disable();
this.tf.disable();
}
,enable:function() {
this.df.enable();
this.tf.enable();
}

jsakalos
19 Feb 2008, 7:36 PM
Thanks, I have overlooked enable/disable functionality.... Are there also readonly methods?

jsakalos
20 Feb 2008, 1:37 AM
Jozef you're a legend! Thanks so much for making this.

One thing I discovered is that disable() and enable() didn't work on the xdatetime field. I just added the following to its methods and it seems to work.


Implementing enable/disable functions is a little bit more tricky as we only want one event to fire. Nevertheless, I've done it - check it out and test it please.

x51596
20 Feb 2008, 7:37 AM
Hi, I am not sure if anybody else experienced this problem. I use the field in a formPanel. If I don't click on the field and just submit the form (onBlur and onFocus is not triggered), only in HTTP request [field-name]-time and [field-name]-date is filled with values, [field-name] is empty. I didn't do any sophisticated fix, just added one listener as a quick fix:

var dateConfig = Ext.apply({}, {
id:this.id + '-date'
,format:this.dateFormat || Ext.form.DateField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
,valid:{scope:this, fn:this.updateHidden}
}
}, this.dateConfig);


PS: thanks for this great extension, I like it a lot

jsakalos
20 Feb 2008, 11:10 AM
Funny... I've tested with the example from the first post (turned allowBlank:true) and I found out the if I do not do anything just submit, dtf, dtf-time and dtf-date are all submitted. Do you have a showcase I can debug locally?

kafsinkaf
27 Feb 2008, 2:10 PM
Hi Saki,

I needed to have setVisible and isVisible functions for your DateTime class and added them into my local copy as



/**
* Hide or show this component by boolean
* @return {Ext.Component} this
*/
,setVisible: function(visible){
if(visible) {
this.df.show();
this.tf.show();
}else{
this.df.hide();
this.tf.hide();
}
return this;
}
// }}}
// {{{
/**
* Returns true if this component is visible
* @return {boolean}
*/
,isVisible : function(){
return this.df.rendered && this.df.getActionEl().isVisible();
}


Could you check if you agree with the implementation and incorporate it to your version so that they will be part of your next release.

Thanks

jsakalos
27 Feb 2008, 2:53 PM
Perfect! Thank you.

I have added also methods show and hide. Grab the new version from the first post.

dawesi
27 Feb 2008, 4:45 PM
Yes, you're right. They are:

<datatimename>-date and <datetimename>-time.



Can you update your component so that if hiddenName is defined, that the date-time field uses that value, or defaults to id if not defined? (for consistancy with other form fields)

currently the form name is taken from the id, but we don't generally specify this as it is normally irrelevant.

jsakalos
27 Feb 2008, 5:09 PM
Well, hidden name is fully supported by combo only. There is method getName that returns hiddenName in Field.js and as DateTime inherits from Field it has it.

On the other hand I agree that there are situations when it can come handy so please add the following line to onRender method just before setting isRendered flag, test it and post back results. I'll do the same in my app and if it doesn't break anything I'll include it in main file:



// setup name for submit
this.el.dom.name = this.hiddenName || this.name || this.id;
/* existing code
// we're rendered flag
this.isRendered = true;

} // eo function onRender
*/

dawesi
27 Feb 2008, 5:31 PM
testing now...

dawesi
27 Feb 2008, 5:47 PM
changed:


// setup name for submit
this.el.dom.name = this.hiddenName || this.name || this.id;
/* existing code
// we're rendered flag
this.isRendered = true;

} // eo function onRender
*/
to:


// setup name for submit
this.el.dom.name = this.hiddenName || this.name || this.id;
/* existing code
// we're rendered flag
this.isRendered = true;
*/
} // eo function onRender
works ok... -date and -time need work too

dawesi
27 Feb 2008, 5:58 PM
this works for me:


initComponent:function() {
// call parent initComponent
Ext.ux.form.DateTime.superclass.initComponent.call(this);

this.id = this.hiddenName || this.name || this.id; // new line

wenner
27 Feb 2008, 9:54 PM
,updateDate:function() {

var d = this.df.getValue();
if(d) {
if(!(this.dateValue instanceof Date)) {
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('');
}
} // eo function updateDate

i setvalue 2008-01-31 , and then setvalue 2008-02-01 , getvalue is return 2008-03-01
i write


this.dateValue.setMonth(1)
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth());
this.dateValue.setDate(d.getDate());

it's work fine!

jsakalos
28 Feb 2008, 12:30 AM
this works for me:


initComponent:function() {
// call parent initComponent
Ext.ux.form.DateTime.superclass.initComponent.call(this);

this.id = this.hiddenName || this.name || this.id; // new line

Well, I don't know what problem are you trying to solve but the above line unconditionally changes id disregarding id that was passed as config value. That is not acceptable as it can lead to many confusions and/or hardly-to-find bugs in applications.

The only purpose of hiddenName is to control the name of POST/GET variable when sending to server. Also, uderlying date and time fields that are posted are generally disregarded by server so their names don't matter. Format of these fields in localized anyway.

jsakalos
28 Feb 2008, 12:34 AM
wenner,

can you please explain - I was able to reproduce it but I can hardly believe that it is bug in DateTime. It seems like some feature/bug of Date object I've overlooked. Also, setMonth(1) sets month to February (0=Jan, 11=Dec) so I'm in complete mystery why it should help if 2 lines later you set date to correct month anyway.

jsakalos
28 Feb 2008, 12:50 AM
I found out the reason - it's leap year. The whole part should read:



this.dateValue.setMonth(0);
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth());
this.dateValue.setDate(d.getDate());




Sets first month to January that is not affected by leap years and then handles the rest.

dirkr
28 Feb 2008, 2:32 AM
Great extension - but I ran into some problems when I use it on a tabbed form with deferredRender: false.
When it's not on the first tab it looks like this (FF2 Win):
http://www.rytlewski.com/test/datetime_2nd_tab.png

First tab looks fine.
2nd tab looks fine with deferredRender: true in this example.

The problem is that I do need deferredRender: false in my real application because the form loads data and the tabs will only be filled without deferred rendering.

Here is cut and paste example code:

function doWindow(){

Ext.BLANK_IMAGE_URL = 'images/ext-2.0.1/resources/images/default/s.gif';

Ext.onReady(function (){
var id = 0;
var win;

var myForm = new Ext.FormPanel({
labelWidth: 75,
frame:true,
bodyStyle:'padding:5px 5px 0',
items: [{
xtype: 'tabpanel',
activeTab: 0,
deferredRender: false,
defaults:{autoHeight:true, bodyStyle:'padding:10px'},
items: [
{
layout: 'form',
title: 'Tab1',
items: [
{xtype: 'textfield', fieldLabel: 'Nr.', name: 'auftragsnummer'},
{xtype: 'xdatetime', fieldLabel: 'Date/Time', name: 'VJ_Termin', timeFormat:'H:i:s',
width: 180, id: 'dtf', timeConfig: {altFormats:'H:i:s',allowBlank:true },
dateFormat:'d.n.Y', dateConfig: {altFormats:'Y-m-d|Y-n-d', allowBlank:true}
}
]
},
{
layout: 'form',
title: 'Tab2',
items: [
{xtype: 'textfield', fieldLabel: 'Nr.', name: 'auftragsnummer2'},
{xtype: 'xdatetime', fieldLabel: 'Date/Time', name: 'VJ_Termin', timeFormat:'H:i:s',
width: 180, id: 'dtf2',timeConfig: {altFormats:'H:i:s',allowBlank:true },
dateFormat:'d.n.Y', dateConfig: {altFormats:'Y-m-d|Y-n-d', allowBlank:true}
}
]
}
]
}],
buttons: [ {
text: 'Speichern',
formBind: true,
handler:function(){
win.close();
}},
{
text: 'Abbruch',
formBind: true,
handler:function(){
win.close();
}
}
]
}
);

win = new Ext.Window({
layout:'fit',
width:500,
height: 300,
closable: true,
resizable: false,
plain: true,
modal: true,
items: [myForm]
});
win.show();
});
}

jsakalos
28 Feb 2008, 2:42 AM
What happens if you use standard DateField instead of DateTime? We need to isolate if the problem is extension related before we start any bug hunting.

wenner
28 Feb 2008, 3:18 AM
I found out the reason - it's leap year. The whole part should read:



this.dateValue.setMonth(0);
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth());
this.dateValue.setDate(d.getDate());




Sets first month to January that is not affected by leap years and then handles the rest.
my code is this.dateValue.setDate(0) and not setMonth , the error not only for leap year, you can try :
1. setvalue(xxxx-xx-31)
2. setvalue(xxxx-mm-xx) mm have 30 days
3. getvalue() - the value is error
and you code above is work fine too ...

poor english .. sorry :/:)/:)

dirkr
28 Feb 2008, 3:21 AM
DateField and TimeField both work. Although there is a rendering issue with the TimeField:
http://www.rytlewski.com/test/datetime_2nd_tab2.png

jsakalos
28 Feb 2008, 4:37 AM
That TimeField issue says that it is not in DateTime. Try hideMode:'offsets' and layoutOnTabChange:true on tab panel.

wolverine4277
28 Feb 2008, 5:13 AM
Great addition as always ;)
Can be a typo the value 'bellow' in place of 'below'?
Regards.

dirkr
28 Feb 2008, 6:40 AM
That TimeField issue says that it is not in DateTime. Try hideMode:'offsets' and layoutOnTabChange:true on tab panel.

Did not work, unfortunately. :s

The only thing that helps is deferredRender: true which leaves initially inactive tabs completely empty or - when used with layoutOnTabChange - filled with input fields but without data.

dirkr
28 Feb 2008, 8:13 AM
Did not work, unfortunately. :s

The only thing that helps is deferredRender: true which leaves initially inactive tabs completely empty or - when used with layoutOnTabChange - filled with input fields but without data.


I'm happy to have to correct myself :)

hideMode: 'offsets' works when applied to all tab panels. Combo boxes, Time Fields and Date Time Fields will render correctly on hidden tabs with deferredRender: false and hideMode: 'offsets'.

Check out this thread: http://extjs.com/forum/showthread.php?t=19450&highlight=combobox+tabs+render

adinata
29 Feb 2008, 3:05 PM
Setting editable to false only propagates to the time field and not to the date field. I tried editable: false in the dateConfig and it does not work.

jsakalos
29 Feb 2008, 5:51 PM
editable is not public property of DateField but it is public property of TimeField (inherited from ComboBox). The conclusion is that DateTime behaves exactly as it should.

If you want the field to be readOnly pass this flag, if disabled then disabled flag but the purpose of the editable flag is per docs:



editable : Boolean False to prevent the user from typing text directly into the field, just like a traditional select (defaults to true)

adinata
3 Mar 2008, 4:13 PM
editable is not public property of DateField but it is public property of TimeField (inherited from ComboBox). The conclusion is that DateTime behaves exactly as it should.

If you want the field to be readOnly pass this flag, if disabled then disabled flag but the purpose of the editable flag is per docs:

So it is impossible to force the user to only select dates from the date picker (and not type them directly).

jsakalos
3 Mar 2008, 4:54 PM
I haven't tried but if it is impossible for standard Ext.DateField it is impossible also for DateTime extension - I'm doing nothing special in this direction with underlying Date field.

dandfra
11 Mar 2008, 9:19 AM
It's a bit difficult to validate the whole field (and not the individual components). For example it's difficult to validate that the date+time is more than a given date and so on... Then we are having some problem because date and time are not fully indipendent (if I only edit the time, the date is automatically set to today for example).

I modified your code to address this problems. Are you interested in accepting our changes in your version?

Here is our modified version:


/**
* 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 11 2008-02-22 17:13:52Z jozo $
*
* @license Ext.ux.form.DateTime is licensed under the terms of
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
* that the code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* License details: http://www.gnu.org/licenses/lgpl.html
*/

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

/**
* @class Ext.ux.form.DateTime
* @extends Ext.form.Field
*/
Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
/**
* @cfg {String/Object} defaultAutoCreate DomHelper element spec
* Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
*/
defaultAutoCreate:{tag:'input', type:'hidden'}
/**
* @cfg {Number} timeWidth Width of time field in pixels (defaults to 100)
*/
,timeWidth:100
/**
* @cfg {String} dtSeparator Date - Time separator. Used to split date and time (defaults to ' ' (space))
*/
,dtSeparator:' '
/**
* @cfg {String} hiddenFormat Format of datetime used to store value in hidden field
* and submitted to server (defaults to 'Y-m-d H:i:s' that is mysql format)
*/
,hiddenFormat:'Y-m-d H:i:s'
/**
* @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
*/
,otherToNow:true
/**
* @cfg {Boolean} emptyToNow Set field value to now if on attempt to set empty value.
* If it is true then setValue() sets value of field to current date and time (defaults to false)
/**
* @cfg {String} timePosition Where the time field should be rendered. 'right' is suitable for forms
* and 'bellow' is suitable if the field is used as the grid editor (defaults to 'right')
*/
,timePosition:'right' // valid values:'bellow', 'right'
/**
* @cfg {String} dateFormat Format of DateField. Can be localized. (defaults to 'm/y/d')
*/
,dateFormat:'m/d/y'
/**
* @cfg {String} timeFormat Format of TimeField. Can be localized. (defaults to 'g:i A')
*/
,timeFormat:'g:i A'
/**
* @cfg {Object} dateConfig Config for DateField constructor.
*/
/**
* @cfg {Object} timeConfig Config for TimeField constructor.
*/

// {{{
/**
* private
* creates DateField and TimeField and installs the necessary event handlers
*/
,initComponent:function() {
// call parent initComponent
Ext.ux.form.DateTime.superclass.initComponent.call(this);
this.validationTask = new Ext.util.DelayedTask(this.validate, this);
// create DateField
var dateConfig = Ext.apply({}, {
id:this.id + '-date'
,format:this.dateFormat || Ext.form.DateField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,validationEvent: false
,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 || Ext.form.TimeField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,validationEvent: false
,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']);

} // eo function initComponent
// }}}
// {{{
/** private
* It buffers the validation events
*/
,filterValidation: function(e){
if(!e.isNavKeyPress()){
this.validationTask.delay(this.validationDelay);
}
}

/**
* private
* Renders underlying DateField and TimeField and provides a workaround for side error icon bug
*/
,onRender:function(ct, position) {
// don't run more than once
if(this.isRendered) {
return;
}

// render underlying hidden field
Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);

// render DateField and TimeField
// create bounding table
var t;
if('bellow' === this.timePosition) {
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 {
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'));
this.df.getEl().on("keyup",this.filterValidation,this);
this.tf.getEl().on("keyup",this.filterValidation,this);

// workaround for IE trigger misalignment bug
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 icon for side invalid errorIcon
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;
}

// we're rendered flag
this.isRendered = true;
this.validate();
} // eo function onRender
// }}}
// {{{
/**
* private
*/
,adjustSize:Ext.BoxComponent.prototype.adjustSize
// }}}
// {{{
/**
* private
*/
,alignErrorIcon:function() {
this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
}
// }}}
// {{{
/**
* private initializes internal dateValue
*/
,initDateValue:function() {
this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
}
/**
* private initializes internal timeValue
*/
,initTimeValue:function() {
this.timeValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
}
// }}}
// {{{
/**
* Disable this component.
* @return {Ext.Component} this
*/
,disable:function() {
if(this.isRendered) {
this.df.disabled = this.disabled;
this.df.onDisable();
this.tf.onDisable();
}
this.disabled = true;
this.df.disabled = true;
this.tf.disabled = true;
this.fireEvent("disable", this);
return this;
} // eo function disable
// }}}
// {{{
/**
* Enable this component.
* @return {Ext.Component} this
*/
,enable:function() {
if(this.rendered){
this.df.onEnable();
this.tf.onEnable();
}
this.disabled = false;
this.df.disabled = false;
this.tf.disabled = false;
this.fireEvent("enable", this);
return this;
} // eo function enable
// }}}
// {{{
/**
* private Focus date filed
*/
,focus:function() {
this.df.focus();
} // eo function focus
// }}}
// {{{
/**
* private
*/
,getPositionEl:function() {
return this.wrap;
}
// }}}
// {{{
/**
* private
*/
,getResizeEl:function() {
return this.wrap;
}
// }}}
// {{{
/**
* @return {Date/String} Returns value of this field
*/
,getValue:function() {
return(this.getDateTime());
} // eo function getValue
// }}}
// {{{
/**
* @return {Boolean} true = valid, false = invalid
* private Calls isValid methods of underlying DateField and TimeField and returns the result
*/
,isValid:function() {
return this.df.isValid() && this.tf.isValid();
} // eo function isValid
// }}}
// {{{
/**
* Returns true if this component is visible
* @return {boolean}
*/
,isVisible : function(){
return this.df.rendered && this.df.getActionEl().isVisible();
} // eo function isVisible
// }}}
// {{{
/**
* private Handles blur event
*/
,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);

} // eo function onBlur
// }}}
// {{{
/**
* private Handles focus event
*/
,onFocus:function() {
if(!this.hasFocus){
this.hasFocus = true;
this.startValue = this.getValue();
this.fireEvent("focus", this);
}
}
// }}}
// {{{
/**
* private Just to prevent blur event when clicked in the middle of fields
*/
,onMouseDown:function(e) {
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
}
// }}}
// {{{
/**
* private
* Handles Tab and Shift-Tab events
*/
,onSpecialKey:function(t, e) {
var key = e.getKey();
if(key == e.TAB) {
if(t === this.df && !e.shiftKey) {
e.stopEvent();
this.tf.focus();
}
if(t === this.tf && e.shiftKey) {
e.stopEvent();
this.df.focus();
}
}
// otherwise it misbehaves in editor grid
if(key == e.ENTER) {
this.updateValue();
}

} // eo function onSpecialKey
// }}}
// {{{
/**
* private Sets the value of DateField
*/
,setDate:function(date) {
this.df.setValue(date);
} // eo function setDate
// }}}
// {{{
/**
* private Sets the value of TimeField
*/
,setTime:function(date) {
this.tf.setValue(date);
} // eo function setTime
// }}}
// {{{
/**
* private
* Sets correct sizes of underlying DateField and TimeField
* With workarounds for IE bugs
*/
,setSize:function(w, h) {
if(!w) {
return;
}
if('bellow' == 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);
}
}
} // eo function setSize
// }}}
// {{{
/**
* @param {Mixed} val Value to set
* Sets the value of this field
*/
,setValue:function(val) {
if(!val && true === this.emptyToNow) {
this.setValue(new Date());
return;
}
else if(!val) {
this.setDate('');
this.setTime('');
this.updateValue();
if(this.rendered){
this.validate()
}
return;
}
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
var da, time;
if(val instanceof Date) {
this.setDate(val);
this.setTime(val);
this.dateValue=new Date(val);
this.timeValue=new Date(val);
}
else {
da = val.split(this.dtSeparator);
this.setDate(da[0]);
if(da[1]) {
this.setTime(da[1]);
}
}
this.updateValue();
if(this.rendered){
this.validate()
}

} // eo function setValue
// }}}
// {{{
/**
* Hide or show this component by boolean
* @return {Ext.Component} this
*/
,setVisible: function(visible){
if(visible) {
this.df.show();
this.tf.show();
}else{
this.df.hide();
this.tf.hide();
}
return this;
} // eo function setVisible
// }}}
//{{{
,show:function() {
return this.setVisible(true);
} // eo function show
//}}}
//{{{
,hide:function() {
return this.setVisible(false);
} // eo function hide
//}}}
// {{{
/**
* private Updates the date part
*/
,updateDate:function() {

var d = this.df.getValue();
if(d) {
if(!(this.dateValue instanceof Date)) {
this.initDateValue();
}
this.dateValue.setMonth(0); // because of leap years
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth());
this.dateValue.setDate(d.getDate());
}
else {
this.dateValue = '';
}
} // eo function updateDate
// }}}
// {{{
/**
* private
* Updates the time part
*/
,updateTime:function() {
var t = this.tf.getValue();
if(t){
if (!(t instanceof Date)) {
t = Date.parseDate(t, this.tf.format);
}
if(!(this.timeValue instanceof Date)) {
this.initTimeValue();
}
this.timeValue.setHours(t.getHours());
this.timeValue.setMinutes(t.getMinutes());
this.timeValue.setSeconds(t.getSeconds());
} else {
this.timeValue='';
}
} // eo function updateTime
// }}}
// {{{
,getDateTime: function(){
if(this.dateValue instanceof Date && this.timeValue instanceof Date){
var dt=new Date();
dt.setHours(this.timeValue.getHours());
dt.setMinutes(this.timeValue.getMinutes());
dt.setSeconds(this.timeValue.getSeconds());
dt.setMonth(0); // because of leap years
dt.setFullYear(this.dateValue.getFullYear());
dt.setMonth(this.dateValue.getMonth());
dt.setDate(this.dateValue.getDate());
return(dt);
} else if(this.dateValue instanceof Date){
return(new Date(this.dateValue));
}
return("");

}
/**
* private Updates the underlying hidden field value
*/
,updateHidden:function() {
if(this.isRendered) {
var value="";
var dt=this.getDateTime();
if(dt instanceof Date){
value=dt.format(this.hiddenFormat);
}
this.el.dom.value = value;
}
}
// }}}
// {{{
/**
* private Updates all of Date, Time and Hidden
*/
,updateValue:function() {

this.updateDate();
this.updateTime();
this.updateHidden();

return;
} // eo function updateValue
// }}}
// {{{
/**
* @return {Boolean} true = valid, false = invalid
* callse validate methods of DateField and TimeField
*/
,validate:function() {
var tValid=this.tf.validate();
var dValid=this.df.validate();
if(dValid){
this.df.clearInvalid();
}
if(tValid){
this.tf.clearInvalid();
}
if(dValid && tValid){
this.updateValue();
return(this.validateValue(this.getValue()));
}
return(false);
} // eo function validate
// }}}
// {{{
,markInvalid: function(msg){
this.df.markInvalid(msg);
this.tf.markInvalid(msg);
}
,clearInvalid: function(){
this.df.clearInvalid();
this.tf.clearInvalid();
}

/**
* Returns renderer suitable to render this field
* @param {Object} Column model config
*/
,renderer: function(field) {
var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
var renderer = function(val) {
var retval = Ext.util.Format.date(val, format);
return retval;
};
return renderer;
} // eo function renderer
// }}}

}); // eo extend

// register xtype
Ext.reg('xdatetime', Ext.ux.form.DateTime);

jsakalos
11 Mar 2008, 10:00 AM
Could you please describe you changes? Sorry, I have no time to dig them out of the full modified code. Also, I'd like more to see only the changed parts. ;)

dandfra
11 Mar 2008, 10:34 AM
The changes are the following essentially:

2 variables to mantain date and time separatly (dateValue and timeValue). This is needed to avoid some interactions beetween the date and time (I select the time and when i lose the focus the date is automatically set and so on)
changed the validation. I disable validation on the single fields, and then I listen for keyup on the whole fields. In the validate method I call the validate method of both time and date, and if both are valid I call the validateValue method. To add custom validation you have to redefine the method. To allow masking to work I had to define the markInvalid and clearInvalid method


The changes (diff -U 5) are the following:

--- DateTimeOrig.js 2008-03-11 19:23:25.000000000 +0100
+++ DateTime.js 2008-03-11 18:26:55.000000000 +0100
@@ -71,17 +71,18 @@
* creates DateField and TimeField and installs the necessary event handlers
*/
,initComponent:function() {
// call parent initComponent
Ext.ux.form.DateTime.superclass.initComponent.call(this);
-
+ this.validationTask = new Ext.util.DelayedTask(this.validate, this);
// create DateField
var dateConfig = Ext.apply({}, {
id:this.id + '-date'
,format:this.dateFormat || Ext.form.DateField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
+ ,validationEvent: false
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
}
}, this.dateConfig);
@@ -92,10 +93,11 @@
var timeConfig = Ext.apply({}, {
id:this.id + '-time'
,format:this.timeFormat || Ext.form.TimeField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
+ ,validationEvent: false
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
}
}, this.timeConfig);
@@ -107,10 +109,19 @@
this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);

} // eo function initComponent
// }}}
// {{{
+ /** private
+ * It buffers the validation events
+ */
+ ,filterValidation: function(e){
+ if(!e.isNavKeyPress()){
+ this.validationTask.delay(this.validationDelay);
+ }
+ }
+
/**
* private
* Renders underlying DateField and TimeField and provides a workaround for side error icon bug
*/
,onRender:function(ct, position) {
@@ -144,10 +155,12 @@
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'));
+ this.df.getEl().on("keyup",this.filterValidation,this);
+ this.tf.getEl().on("keyup",this.filterValidation,this);

// workaround for IE trigger misalignment bug
if(Ext.isIE && Ext.isStrict) {
t.select('input').applyStyles({top:0});
}
@@ -165,11 +178,11 @@
this.tf.errorIcon = this.errorIcon;
}

// we're rendered flag
this.isRendered = true;
-
+ this.validate();
} // eo function onRender
// }}}
// {{{
/**
* private
@@ -189,10 +202,16 @@
* private initializes internal dateValue
*/
,initDateValue:function() {
this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
}
+ /**
+ * private initializes internal timeValue
+ */
+ ,initTimeValue:function() {
+ this.timeValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
+ }
// }}}
// {{{
/**
* Disable this component.
* @return {Ext.Component} this
@@ -254,12 +273,11 @@
// {{{
/**
* @return {Date/String} Returns value of this field
*/
,getValue:function() {
- // create new instance of date
- return this.dateValue ? new Date(this.dateValue) : '';
+ return(this.getDateTime());
} // eo function getValue
// }}}
// {{{
/**
* @return {Boolean} true = valid, false = invalid
@@ -415,27 +433,35 @@
}
else if(!val) {
this.setDate('');
this.setTime('');
this.updateValue();
+ if(this.rendered){
+ this.validate()
+ }
return;
}
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
var da, time;
if(val instanceof Date) {
this.setDate(val);
this.setTime(val);
- this.dateValue = new Date(val);
+ this.dateValue=new Date(val);
+ this.timeValue=new Date(val);
}
else {
da = val.split(this.dtSeparator);
this.setDate(da[0]);
if(da[1]) {
this.setTime(da[1]);
}
}
this.updateValue();
+ if(this.rendered){
+ this.validate()
+ }
+
} // eo function setValue
// }}}
// {{{
/**
* Hide or show this component by boolean
@@ -470,61 +496,72 @@

var d = this.df.getValue();
if(d) {
if(!(this.dateValue instanceof Date)) {
this.initDateValue();
- if(!this.tf.getValue()) {
- this.setTime(this.dateValue);
- }
}
this.dateValue.setMonth(0); // because of leap years
this.dateValue.setFullYear(d.getFullYear());
this.dateValue.setMonth(d.getMonth());
this.dateValue.setDate(d.getDate());
}
else {
this.dateValue = '';
- this.setTime('');
}
} // eo function updateDate
// }}}
// {{{
/**
* private
* Updates the time part
*/
,updateTime:function() {
var t = this.tf.getValue();
- if(t && !(t instanceof Date)) {
+ if(t){
+ if (!(t instanceof Date)) {
t = Date.parseDate(t, this.tf.format);
- }
- if(t && !this.df.getValue()) {
- this.initDateValue();
- this.setDate(this.dateValue);
- }
- if(this.dateValue instanceof Date) {
- 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);
- }
+ }
+ if(!(this.timeValue instanceof Date)) {
+ this.initTimeValue();
+ }
+ this.timeValue.setHours(t.getHours());
+ this.timeValue.setMinutes(t.getMinutes());
+ this.timeValue.setSeconds(t.getSeconds());
+ } else {
+ this.timeValue='';
}
} // eo function updateTime
// }}}
// {{{
+ ,getDateTime: function(){
+ if(this.dateValue instanceof Date && this.timeValue instanceof Date){
+ var dt=new Date();
+ dt.setHours(this.timeValue.getHours());
+ dt.setMinutes(this.timeValue.getMinutes());
+ dt.setSeconds(this.timeValue.getSeconds());
+ dt.setMonth(0); // because of leap years
+ dt.setFullYear(this.dateValue.getFullYear());
+ dt.setMonth(this.dateValue.getMonth());
+ dt.setDate(this.dateValue.getDate());
+ return(dt);
+ } else if(this.dateValue instanceof Date){
+ return(new Date(this.dateValue));
+ }
+ return("");
+
+ }
/**
* private Updates the underlying hidden field value
*/
,updateHidden:function() {
if(this.isRendered) {
- var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
- this.el.dom.value = value;
+ var value="";
+ var dt=this.getDateTime();
+ if(dt instanceof Date){
+ value=dt.format(this.hiddenFormat);
+ }
+ this.el.dom.value = value;
}
}
// }}}
// {{{
/**
@@ -543,14 +580,35 @@
/**
* @return {Boolean} true = valid, false = invalid
* callse validate methods of DateField and TimeField
*/
,validate:function() {
- return this.df.validate() && this.tf.validate();
+ var tValid=this.tf.validate();
+ var dValid=this.df.validate();
+ if(dValid){
+ this.df.clearInvalid();
+ }
+ if(tValid){
+ this.tf.clearInvalid();
+ }
+ if(dValid && tValid){
+ this.updateValue();
+ return(this.validateValue(this.getValue()));
+ }
+ return(false);
} // eo function validate
// }}}
// {{{
+ ,markInvalid: function(msg){
+ this.df.markInvalid(msg);
+ this.tf.markInvalid(msg);
+ }
+ ,clearInvalid: function(){
+ this.df.clearInvalid();
+ this.tf.clearInvalid();
+ }
+
/**
* Returns renderer suitable to render this field
* @param {Object} Column model config
*/
,renderer: function(field) {

jsakalos
11 Mar 2008, 10:40 AM
Re 1) There is configuration option otherToNow that is true by default. Try to set it to false
Re 2) I still don't quite get what it would bring to me or what problem does it solve.

dandfra
12 Mar 2008, 12:52 AM
With the original code try the following: select the hour and then click on the date. What happens is the following:

With otherToNow=true, the date is automatically populated to the actual one + the hour selected
With otherToNow=false, the date is automatically populated to 1970-01-01 + the hour selected

This is not what our users expect it seems. If they only select the hour they don't want the date prepopulated, they want to populate it themselves. So I added a new variable timeValue, to keep separate the date and the time so that when I enter the second the first is not automatically populated.
We had to make a validation check on the whole date (the value entered must be greater than now + <x time>). With my changes to add the check I simply do this:


dateTimeField=new Ext.ux.form.DateTime({...});
dateTimeField.validateValue=function(value){
//value is a date, here I can check if it's greater than now - x
}

I don't see an easy way to perform the check with the original code

jsakalos
12 Mar 2008, 3:34 AM
I see,

Re 1) seems to be bug - I'll take a look at it. Other value should stay empty.
Re 2) I'll take a look.

Thank you for pointing out.

LedrickLeron
19 Mar 2008, 2:43 PM
Is there a way to stack the date and time fields ontop of each other instead of inline??? I have looked through this entire thread twice now every word every comment... I am at a loss now

I want to use this badly but I have Panel that is only maxWidth: 240 (resizable/collapsable) and I would like to have them stacked vs, inline

jsakalos
19 Mar 2008, 3:08 PM
Try timePosition:'bellow'.

LedrickLeron
19 Mar 2008, 3:28 PM
You are a saint and a scholar and a time saver.... was this listed? Or is it in your code? By the way, BEAUTIFUL code !

jsakalos
19 Mar 2008, 3:30 PM
Documentation of the configuration options is written in Ext-style in the comments in the code.

I'm glad you like it. :)

Enjoy.

vcastel
21 Mar 2008, 8:50 AM
first of all, thanks for the extension, that's exactly what I'm looking for.

unfortunately, nothing happens like I want to :
the script is loaded (firebug)
but when I try to open the panel, since I use a "xtype : xdatetime" in my form
I have this error :
"this[func] is not a function"
in
"Date.prototype.format0 = function(){return "

help please

jsakalos
21 Mar 2008, 11:57 AM
Try to change xtype to 'datefield' to find out if the error is related to the extension.

vcastel
25 Mar 2008, 1:37 AM
Try to change xtype to 'datefield' to find out if the error is related to the extension.
when the xtype was datefield (or timefield), no error.

We solved this by using the good version of ext-datetime (my mistake).

jsakalos
25 Mar 2008, 1:43 AM
Is the problem resolved then?

vcastel
25 Mar 2008, 1:57 AM
Yes.
thx.

infinit
27 Mar 2008, 1:59 AM
I configured my xdatetime field as this :


{ fieldLabel: 'Will post at',name: 'will_post_at', xtype:'xdatetime',dateFormat: 'Y/m/d', timeFormat: 'H:i:s',dateConfig: {allowBlank:false }, timeConfig: {allowBlank:false} }

but if I left the xdatefield blank, no warnings show, can anyone help?
thanks

jsakalos
27 Mar 2008, 2:33 AM
Try this:


<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css">
<script type="text/javascript" src="../ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext/ext-all-debug.js"></script>
<script type="text/javascript" src="../js/Ext.ux.form.DateTime.js"></script>
<script type="text/javascript">

Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif';
Ext.onReady(function() {
Ext.QuickTips.init();
var win = new Ext.Window({
width:500
,id:'winid'
,height:300
,layout:'fit'
,border:false
,closable:false
,title:Ext.get('title').dom.innerHTML
,items:[{
xtype:'form'
,id:'formid'
,frame:true
,url:'submit.php'
,items:[{
xtype:'xdatetime'
,fieldLabel:'DateTime'
,dateConfig:{allowBlank:false}
,timeConfig:{allowBlank:false}
,name:'datatime'
,id:'datetimeid'
}]
,buttons:[{
text:'Submit'
,handler:function() {
this.ownerCt.getForm().submit();
}
}]
}]
});
win.show();
});
</script>
<title id="title">X controls test</title>
</head>
<body>
</body>
</html>

kevinwu8
31 Mar 2008, 9:47 PM
Hi...

When i use this plugin in my ap that i disabled this datetime field...
everything run in FF is worked fine..
but in IE..look like ok...But i click this disabled datetime field...
my ie show the error..

ERROR:'target.nodeName' is NULL or not a object...

and i use Microsoft Script Debugger to show what's happen..
Debugger show break on Code is..


,onMouseDown:function(e) {
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
}

how to solve this error??

jsakalos
1 Apr 2008, 4:33 AM
/**
* private Just to prevent blur event when clicked in the middle of fields
*/
,onMouseDown:function(e) {
if(!this.disabled) {
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
}
}

kevinwu8
1 Apr 2008, 9:54 PM
Hi...Jozef Sakalosit's workable now..
very thanks to you..

derbbre
15 Apr 2008, 12:46 PM
Please forgive me if this is a native language / language translation issue, but as the rest of the plugin seems to be written and documented in English, I thought I'd point out that the config option "bellow" for timePosition should be "below". I wouldn't even bring this up except that it is a user-configurable option and it might be hard to remember or be confusing.


...
,setSize:function(w, h) {
if(!w) {
return;
}
if('bellow' == this.timePosition) {
this.df.setSize(w, h);
...

should perhaps be


...
,setSize:function(w, h) {
if(!w) {
return;
}
if('below' == this.timePosition) {
this.df.setSize(w, h);
...

and of course the related comments. The word 'below' relates to position while 'bellow' relates to a load utterance or growl.

Thanks very much for your hard work. This is a great ux! :D

jsakalos
15 Apr 2008, 2:06 PM
It's already been corrected, please check the first post.

jsakalos
15 Apr 2008, 2:07 PM
Sorry, I've corrected it locally but now I've corrected it also in that first post.

bjw5392
21 Apr 2008, 11:58 AM
The datetime control is working great for me in Firefox and IE7, but I'm having a small display problem in IE6. When I have a datetime control on the second tab of a tabbed panel which is in a split window, it won't show until I manually resize the panel which contains the datetime control. I don't have this problem in IE7 or Firefox. If I set the deferredRender flag to false in the tabbed panel config, the problem partially goes away in IE6, but there is some overlap of the date picker and time picker. Also, setting the deferredRender flag to false ends up causing a lot of overlap of the date picker and time picker in Firefox. I've attached several screenshots to show what I'm talking about. I also tried setting layoutOnTabChange to true, but it made no difference. Here is some of my test code to reproduce the problem.



// make sure namespace exists
Ext.namespace('Test');

// create extension
Test.Window = Ext.extend(Ext.Window, {

// configurables
width: 800,
height: 550,
// eo configurables

// initialization method
initComponent: function() {

Ext.apply(this, {
title: 'Test',
constrain: true,
layout: 'border',
resizable: true,
maximizable: true,
closable: true,
items: [{
xtype: 'panel',
region: 'west',
width: 400,
split: true,
collapsible: true,
collapseMode: 'mini',
layout: 'fit',
items: [{
xtype: 'tabpanel',
deferredRender: false,
activeTab: 0,
items: [{
title: 'Tab 1',
html: 'stuff'
}, {
xtype: 'testformpanel',
title: 'Tab 2'
}]
}]
}, {
region: 'center',
html: 'stuff',
minWidth: 200
}]
}); // eo apply

// call parent initialization method
Test.Window.superclass.initComponent.apply(this, arguments);

} // eo initComponent

}); // eo extend

// register xtype
Ext.reg('testwindow', Test.Window);




// make sure namespace exists
Ext.namespace('Test');

// create extension
Test.FormPanel = Ext.extend(Ext.FormPanel, {

// initialization method
initComponent: function() {

Ext.apply(this, {
frame: true,
bodyStyle: 'padding: 5px;',
items: [{
xtype: 'combo',
fieldLabel: 'Furnace',
name: 'furnace',
width: 203
}, {
xtype: 'combo',
fieldLabel: 'Filter By',
name: 'filterBy',
width: 203
}, {
xtype: 'textfield',
fieldLabel: 'Filter',
name: 'filter',
width: 203
}, {
xtype: 'xdatetime',
fieldLabel: 'Start Date',
name: 'startDate',
dateFormat:'Y-m-d',
dateConfig: {
value:new Date(),
altFormats:'Y/m/d|m-d-Y|m/d/Y',
allowBlank:false
},
timeFormat:'H:i:s',
timeConfig: {
value:'00:00:00',
altFormats:'H:i:s',
allowBlank:false
}
}, {
xtype: 'xdatetime',
fieldLabel: 'End Date',
name: 'endDate',
dateFormat:'Y-m-d',
dateConfig: {
value:new Date(),
altFormats:'Y/m/d|m-d-Y|m/d/Y',
allowBlank:false
},
timeFormat:'H:i:s',
timeConfig: {
value:'00:00:00',
altFormats:'H:i:s',
allowBlank:false
}
}]
}); // eo apply

// call parent initialization method
Test.FormPanel.superclass.initComponent.apply(this, arguments);

} // eo initComponent

}); // eo extend

// register xtype
Ext.reg('testformpanel', Test.FormPanel);


I've tinkered with the datetime extension code, but can't figure out how to fix the display problem. I don't even know if the problem lies within the datetime extension code.

Saki, can you see what is causing my problem?

Thanks a lot,
Bryan

EDIT: If the panel with datetime control is on the first tab, then no display problems. Also, If I layout the tabbed panel without a split window, then no display problems.

jsakalos
21 Apr 2008, 12:29 PM
There is the code that should handle it:


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


Could you somehow check if the width is really set in IE? If yes, you can try to play with zoom:1 css rule on some upper level containers. Also, remove doctype, if any.

bjw5392
22 Apr 2008, 5:40 AM
I fixed my problem. I nested the form panel within another panel that has a border layout. I set the form panel region to center and gave it an explicit height. I also explicitly set the width of the datetime controls, but I don't think that mattered for my problem. The last thing I had to do, which took me awhile to figure out, was increase the initial size of the west region which contained the form's tabbed panel. I increased from 350px to 375px. The 350px looked like it was plenty enough room to display the datetime control, but for some reason IE wanted more. Now I have a large empty space between the form elements and the right edge of the west region. You can see in the attached pic. Also, here is my updated test code...



// make sure namespace exists
Ext.namespace('Test');

// create extension
Test.Window = Ext.extend(Ext.Window, {

// configurables
width: 800,
height: 550,
// eo configurables

// initialization method
initComponent: function() {

Ext.apply(this, {
title: 'Test',
constrain: true,
layout: 'border',
resizable: true,
maximizable: true,
closable: true,
items: [{
xtype: 'panel',
region: 'west',
width: 375,
split: true,
collapsible: true,
collapseMode: 'mini',
layout: 'fit',
items: [{
xtype: 'tabpanel',
activeTab: 0,
items: [{
title: 'Tab 1',
html: 'stuff'
}, {
xtype: 'testformpanel',
title: 'Tab 2'
}]
}]
}, {
region: 'center',
html: 'stuff',
minWidth: 200
}]
}); // eo apply

// call parent initialization method
Test.Window.superclass.initComponent.apply(this, arguments);

} // eo initComponent

}); // eo extend

// register xtype
Ext.reg('testwindow', Test.Window);




// make sure namespace exists
Ext.namespace('Test');

// create extension
Test.FormPanel = Ext.extend(Ext.Panel, {

// initialization method
initComponent: function() {

Ext.apply(this, {
layout: 'border',
frame: true,
bodyStyle: 'padding: 5px;',
items: [{
region: 'center',
xtype: 'form',
height: 175,
plain: true,
border: false,
items: [{
xtype: 'combo',
fieldLabel: 'Furnace',
name: 'furnace',
width: 200
}, {
xtype: 'combo',
fieldLabel: 'Filter By',
name: 'filterBy',
width: 200
}, {
xtype: 'textfield',
fieldLabel: 'Filter',
name: 'filter',
width: 200
}, {
xtype: 'xdatetime',
fieldLabel: 'Start Date',
name: 'startDate',
dateFormat:'Y-m-d',
dateConfig: {
value:new Date(),
altFormats:'Y/m/d|m-d-Y|m/d/Y',
allowBlank:false
},
timeFormat:'H:i:s',
timeConfig: {
value:'00:00:00',
altFormats:'H:i:s',
allowBlank:false
},
timeWidth: 100,
width: 200
}, {
xtype: 'xdatetime',
fieldLabel: 'End Date',
name: 'endDate',
dateFormat:'Y-m-d',
dateConfig: {
value:new Date(),
altFormats:'Y/m/d|m-d-Y|m/d/Y',
allowBlank:false
},
timeFormat:'H:i:s',
timeConfig: {
value:'00:00:00',
altFormats:'H:i:s',
allowBlank:false
},
timeWidth: 100,
width: 200
}],
buttons: [{
text: 'Load',
type: 'submit'
}]
}]
}); // eo apply

// call parent initialization method
Test.FormPanel.superclass.initComponent.apply(this, arguments);

} // eo initComponent

}); // eo extend

// register xtype
Ext.reg('testformpanel', Test.FormPanel);

jsakalos
22 Apr 2008, 6:21 AM
Pic looks nice, not irritating or unbalanced. I'm glad you won over IE ;)

jenner
24 Apr 2008, 1:30 AM
Hi there,

there's a small problem with Datetime when you need to listen on valid/invalid events - the field value is not updated, since the updates are triggered in onBlur. A quick fix is to add valid and invalid event listeners to date and time fields:


// create DateField
var dateConfig = Ext.apply({}, {
id:this.id + '-date'
,format:this.dateFormat || Ext.form.DateField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
,valid:{scope:this, fn:this.onBlur}
,invalid:{scope:this, fn:this.onBlur}
}
}, 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 || Ext.form.TimeField.prototype.format
,width:this.timeWidth
,selectOnFocus:this.selectOnFocus
,listeners:{
blur:{scope:this, fn:this.onBlur}
,focus:{scope:this, fn:this.onFocus}
,valid:{scope:this, fn:this.onBlur}
,invalid:{scope:this, fn:this.onBlur}
}
}, this.timeConfig);
this.tf = new Ext.form.TimeField(timeConfig);
delete(this.timeFormat);

conorarmstrong
25 Apr 2008, 10:53 AM
This component is excellent, and I've had it working well for me in Extjs 2.0.x

However, the dateFormat property seems to be causing me difficulties in extjs 2.1

Originally I had had the component configured as:



xtype:'xdatetime',
fieldLabel:'Starts',
timeFormat:'h:ia',
timeConfig: {
altFormats:'H:i:s',
allowBlank:true
},
dateFormat:'d-M-Y',
dateConfig: {
altFormats:'Y-m-d|Y-n-d',
allowBlank:true
},
name:'starttime'


Although fine in extjs 2.0.x, in 2.1 this continually triggers a validation error. Removing (or commenting out) the custom dateFormat seems to fix it as follows:



xtype:'xdatetime',
fieldLabel:'Starts',
timeFormat:'h:ia',
timeConfig: {
altFormats:'H:i:s',
allowBlank:true
},
//dateFormat:'d-M-Y',
dateConfig: {
altFormats:'Y-m-d|Y-n-d',
allowBlank:true
},
name:'starttime'



...not an ideal solution.

I have traced the problem back the code from ext-all-debug.js which I see has been rewritten. In particular, the Date.createParser function doesn't seem to be working right in creating a parser for d-M-Y (It produces a parser function that always returns undefined).

Has anyone else experienced anything similar or have a solution?

conorarmstrong
25 Apr 2008, 11:02 AM
I've discovered that this is a bug in the Date field and a fix is here:-

http://www.extjs.com/forum/showthread.php?t=33112

FoGhost
26 Apr 2008, 7:41 PM
When i set a default value to a DateTimeField named inDateTime,
it seemed to have one bug in inDateTime.el.dom.value's initialization because "inDateTime.isRendered=false"


/**
* private Updates the underlying hidden field value
*/
,updateHidden:function() {
if(this.isRendered) {
var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
this.el.dom.value = value;
}
}

So i make a little modification in the end of DateTimeField's onRender() function


// we're rendered flag
this.isRendered = true;
this.updateHidden();
} // eo function onRender

Maybe there's something i missed when i used this great extension for leading to the above 'error'.If it does,please let me know. Thank you ! Sorry for my poor english.

jsakalos
27 Apr 2008, 4:50 AM
@FoGhost,

yes, you're right. I've put updateHidden() call to the main code.

Thank you for pointing out and finding the solution.

keypoint
28 Apr 2008, 2:09 PM
This post (http://extjs.com/forum/showthread.php?p=136670#post136670) does have something useful: in the current state, the fields don't validate on blur, but only on submit. Blur validation would be a plus, at least for me ;)
Actually what he added was keyup validation. Blur would still be nicer.

jsakalos
28 Apr 2008, 4:14 PM
Well, I not sure that I'm no missing something here. I have done nothing to individual fields validation so both Date and Time validate themselves the standard Ext way.

predragp
2 May 2008, 12:25 PM
This is probably easy but I can not figure out how to solve this problem.

I'm loading xdatetime field with data from database using simple JSON loading but always get wrong dates in field.
This is modified demo example that I use as a test case:

Ext.onReady(function() {
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
var win = new Ext.Window({
width:500
,id:'winid'
,height:300
,layout:'fit'
,border:false
,closable:false
,title:'Ext.ux.form.DateTime Example'
,items:[{
xtype:'form'
,frame:true
,labelWidth:100
,id:'form'
,url:'.'
,items:[{
xtype:'xdatetime'
,id:'dtf'
,name: 'od'
,fieldLabel:'Date & Time'
// ,width:360
,anchor:'-18'
,timeFormat:'H:i:s'
,timeConfig: {
altFormats:'H:i:s'
,allowBlank:true
}
,dateFormat:'d.m.Y'
,dateConfig: {
altFormats: 'Y-m-d|d.m.Y',
}
}]
}]
,loadData: function(id) {
this.items.itemAt(0).getForm().load({
url: 'rezervacija/get',
waitMsg: 'loading...',
params: {id: id},
});
}
});
win.show()
win.loadData(1);
});Server returns this JSON data:

{"success":true,"data":{"id":"1","od":"2008-04-09 00:00:00"}}but when form get loaded with date, value in the xdatetime field is : 29.09.1914
So it looks that he parsing loaded date using 'd.m.Y' format and gets this silly result. So what is the proper way for me to load data in this field.

Sorry if this is "stupid" question but I'm still pretty new with extjs :)

Tnx

keypoint
6 May 2008, 1:54 PM
If you're using Ext 2.1, chances are you ran into the newly introduced date bug. Add this to a js file loaded by all your pages:



Ext.apply(Date.parseCodes, {
j: {
g:1,
c:"d = parseInt(results[{0}], 10);\n",
s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31)
},
M: function() {
for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names
return Ext.applyIf({
s:"(" + a.join("|") + ")"
}, Date.formatCodeToRegex("F"));
},
n: {
g:1,
c:"m = parseInt(results[{0}], 10) - 1;\n",
s:"(\\d{1,2})" // month number without leading zeros (1 - 12)
},
o: function() {
return Date.formatCodeToRegex("Y");
},
g: function() {
return Date.formatCodeToRegex("G");
},
h: function() {
return Date.formatCodeToRegex("H");
},
P: function() {
return Ext.applyIf({
s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator)
}, Date.formatCodeToRegex("O"));
}
});

// private
Date.formatCodeToRegex = function(character, currentGroup) {
// Note: currentGroup - position in regex result array (see notes for Date.parseCodes above)
var p = Date.parseCodes[character];

if (p) {
p = Ext.type(p) == 'function'? p() : p;
Date.parseCodes[character] = p; // reassign function result to prevent repeated execution
}

return p? Ext.applyIf({
c: p.c? String.format(p.c, currentGroup || "{0}") : p.c
}, p) : {
g:0,
c:null,
s:Ext.escapeRe(character) // treat unrecognised characters as literals
}
};

mystix
7 May 2008, 12:21 AM
If you're using Ext 2.1, chances are you ran into the newly introduced date bug.

righto. just fyi, the reference to the bug report can be found here:
http://extjs.com/forum/showthread.php?t=33112

ray007
9 May 2008, 3:12 AM
Last night we upgraded to the last version of this extension and some of our form broke.
The old version did accept a number as initial value to initialize the date with, while the new version does not.

adding a check


if (typeof val == 'number') {
val = new Date(val);
}
to the setValue() method solves the problem.

jsakalos
9 May 2008, 5:20 AM
Where exactly did you put it? In setValue? Looks like my omission so I'll put it back. Post please the complete setValue function.

ray007
9 May 2008, 7:00 AM
Where exactly did you put it? In setValue? Looks like my omission so I'll put it back. Post please the complete setValue function.



/**
* @param {Mixed} val Value to set
* Sets the value of this field
*/
,setValue:function(val) {
if(!val && true === this.emptyToNow) {
this.setValue(new Date());
return;
}
else if(!val) {
this.setDate('');
this.setTime('');
this.updateValue();
return;
}
if (typeof val == 'number') {
val = new Date(val);
}
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
var da, time;
if(val instanceof Date) {
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();
} // eo function setValue
should probably be "else if(...)", but it works this way ;)

jsakalos
9 May 2008, 7:06 AM
Doesn't need to be - it's fine as it is. Putting it to code...

aacraig
11 May 2008, 7:48 AM
Using the following code, the datetime field renders correctly, but doesn't hide the applied to field.



<html>
<head>
</head>
<body>
<link rel="stylesheet" type="text/css" href="javascript/ext-2.1/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="javascript/ext-2.1/resources/css/xtheme-gray.css" />
<script src="javascript/ext-2.1/adapter/ext/ext-base.js"></script>
<script src="javascript/ext-2.1/ext-all-debug.js"></script>
<script src="javascript/ext-2.1/ux/DateTime/Ext.ux.form.DateTime.js"></script>
<input id='test-date' value='05/19/2008 12:05 AM'>
<script>
new Ext.ux.form.DateTime
({
applyTo: 'test-date'
});

</script>
</body>
</html>


If I replace the constructor with Ext.form.DateField, my original field is hidden.

Here's a screen shot:

jsakalos
11 May 2008, 4:00 PM
I personally do not support applyTo in my extensions (although Ext does) as I don't consider it a good coding practice to generate a html and then to apply some Ext component to it.

Html should be generated by Ext and not reversed.

aacraig
11 May 2008, 10:48 PM
I personally do not support applyTo in my extensions (although Ext does) as I don't consider it a good coding practice to generate a html and then to apply some Ext component to it.

Html should be generated by Ext and not reversed.

I respect your point of view, though I feel that a good software component should always seek to offer flexibility to the developer.

In my case, I am using Ext.Template to create HTML fragments that are used when the user adds new items to a list. The EditorGrid doesn't offer the layout flexibility I require, so that component isn't an option.

Unless there is a way to embed the DateTime field in the HTML code that creates the fragment, I don't see any other way to get the functionality I need other than applying the field to the HTML that is generated (which, funnily enough, *IS* generated by Ext -- through the Ext.Template object).

At any rate, if you are against checking into this for philosophical reasons, I understand, and will have to figure it out on my own.

Respectfully,

jsakalos
12 May 2008, 1:24 AM
Why not to generate only container and then renderTo it? This is standard way that completely changes the situation. I thought you're trying to applyTo to some unchangable html markup but if you are generating markup with Template you're free to choose how you do it.

Once again: generate only container, a div, and then specify this container as renderTo of DateTime.

aacraig
12 May 2008, 6:43 AM
Why not to generate only container and then renderTo it? This is standard way that completely changes the situation. I thought you're trying to applyTo to some unchangable html markup but if you are generating markup with Template you're free to choose how you do it.

Once again: generate only container, a div, and then specify this container as renderTo of DateTime.

I've done as you suggested and now get the control to render into a div.

However, now I have a second issue, which may or may not be related. If I put only one DateTime field in my row, I have no problem. As soon as I put another one immediately after, however, I get an error while rendering the second DateTime field.

I've put together a test case to demonstrate the problem:



<html>
<head>
<link rel="stylesheet" type="text/css" href="javascript/ext-2.1/resources/css/ext-all.css" />
<script src="javascript/ext-2.1/adapter/ext/ext-base.js"></script>
<script src="javascript/ext-2.1/ext-all-debug.js"></script>
<script src="javascript/ext-2.1/ux/DateTime/Ext.ux.form.DateTime.js"></script>
</head>
<body>
<div id="datefield1"></div>
<div id="datefield2"></div>

<script>
Ext.form.Field.prototype.msgTarget = 'side';
new Ext.ux.form.DateTime
({
renderTo: "datefield1"
});
new Ext.ux.form.DateTime
({
renderTo: "datefield2"
});
</script>
</body>
</html>


This will generate the following error:
elp has no properties
http://localhost/ebs/javascript/ext-2.1/ux/DateTime/Ext.ux.form.DateTime.js
Line 166

However, if you comment the line:

Ext.form.Field.prototype.msgTarget = 'side';
out, you'll see that the second field renders just fine.

jsakalos
12 May 2008, 9:01 AM
It's most likely that container does not exist when rendering into it but is created later...

Arthur.Blake
12 May 2008, 9:24 AM
I am trying to use your plugin, and for some reason the date and time fields overlap no matter how I try to render it-- right now I'm trying to render it into simple divs (I've also tried using a simple form panel and it overlaps the same way...)

html:

Start Date: <div id='startdatecontent'></div>
End Date: <div id='enddatecontent'></div>

javascript:

new Ext.ux.form.DateTime({renderTo: "startdatecontent"});
new Ext.ux.form.DateTime({renderTo: "enddatecontent"});

The overlapping occurs in both IE and FF.. but it's much worse in FF:

6763

Any idea on what I am doing wrong?

jsakalos
12 May 2008, 9:43 AM
Try to set timeWidth or try to set some dimensions on their container or both. To fully understand the sizing take a look at setSize function; it is the simple one.

Arthur.Blake
12 May 2008, 11:32 AM
The problem was that my two divs were children of another div that is set to display:none when the DateTime fields are created. With FireBug I can see that it is trying to set the size of the date field to a negative value. No amount of changing the geometry of the fields or the divs they are in helped.

But, I can get it to work if I manually call setSize on the fields after the div is shown. It seems like I shouldn't have to do this... but at least I have a workaround for now...

Thanks

jsakalos
12 May 2008, 11:42 AM
Rendering to display:none container === problem. Always.

Arthur.Blake
12 May 2008, 11:45 AM
Problem always with all the Ext components, or just with the DateTime plugin?
How can I build up a component beforehand while it is hidden and then show and hide it?
Sorry if this is a noob question, but I am fairly new to Ext... :">

jsakalos
12 May 2008, 12:12 PM
Always, with all Ext Components.

As to application design: Have you read this: Writing a Big Application in Ext (http://extjs.com/forum/../learn/Tutorial:Writing_a_Big_Application_in_Ext) ?

Arthur.Blake
12 May 2008, 12:34 PM
Thanks Saki. I had not read that tutorial before, but I just read it now. The main problem is that I am integrating some Ext components into a very large, existing web application, and so it has to interact with several already existing frameworks and HTML. I gather that the Ext solution to the problem is to use the so called lazy rendering, where a component will automatically render when it is first shown.

I am rewriting parts of our application little by little over time so that I can do things in a more Object Oriented way "the Ext way?".

Your plugins and posts have been very helpful and I really appreciate them!

Thanks again.

jsakalos
12 May 2008, 2:42 PM
I wish you good luck!

It's quite a job to rewrite it... =D>

abraxxa
15 May 2008, 10:11 AM
First, great extension!

Does it support vtypes?
I tried to use it with the date range code from the advanced validation example: http://extjs.com/deploy/dev/examples/form/adv-vtypes.html (http://extjs.com/forum/../deploy/dev/examples/form/adv-vtypes.html)

I still can select every date but the time always jumps back to midnight.

jsakalos
15 May 2008, 12:14 PM
I didn't implement anything connected to vtypes to the whole field but underlying Date and Time Fields do support them as they are standard Ext fields. There are dateConfig and timeConfig options that are passed directly to the underlying fields - you can try to experiment with them.

abraxxa
15 May 2008, 12:17 PM
Can I access the combined date + time value somehow?

jsakalos
15 May 2008, 12:28 PM
Best is if you take a look at the source code. For sure you can use getValue() but privately you can maybe also access value property.

abraxxa
16 May 2008, 5:11 AM
After some trying around and using firebug I found out how it works best:

The vtype 'daterange' is taken from the advanced validation example without a change.
The vtype and its options has to be specified in the config hash for the datefield.

I found out that you generate id's for the date and time field so I can use them for the vtype.

If anybody has questions about the code please ask.

@jsakalos:
If you want to include the code as example for vtype usage with your ux feel free to use it. ;)
Maybe you should point out in the docs that the DateField can be accessed with .df and the TimeField with .tf!


var form_add_maintenance = new Ext.FormPanel({
labelWidth:100,
frame:true,
title:'Add maintenance',
bodyStyle:'padding:5px 5px 0',
width:400,
defaults:{width:250},
defaultType:'textfield',
renderTo:'form-maintenance',
items: [{
fieldLabel:'Description',
name:'description',
allowBlank:false
},{
xtype:'xdatetime',
fieldLabel:'Start Date/Time',
id:'datetime_start',
name:'datetime_start',
dateFormat:Date.patterns.Date,
dateConfig: {
allowBlank:false,
emptyText:'YYYY-MM-DD',
vtype:'daterange',
endDateField:'datetime_end-date' // id of the end date field
},
timeFormat:Date.patterns.TimeShort,
timeConfig: {
allowBlank:false,
emptyText:'HH:MM'
}
},{
xtype:'xdatetime',
fieldLabel:'End Date/Time',
id:'datetime_end',
name:'datetime_end',
dateFormat:Date.patterns.Date,
dateConfig: {
allowBlank:false,
emptyText:'YYYY-MM-DD',
vtype:'daterange',
startDateField:'datetime_start-date' // id of the start date field
},
timeFormat:Date.patterns.TimeShort,
timeConfig: {
allowBlank:false,
emptyText:'HH:MM'
}
}
],
buttons: [{
text:'Save',
handler:function(){
form_add_maintenance.getForm().submit({url:'/create-maintenance.epl', method:'GET', waitMsg:'Saving Data...'});
}
}]
});

abraxxa
16 May 2008, 8:49 AM
I've got a patch for you:


// {{{
/**
* Calls clearInvalid on the DateField and TimeField
*/
,clearInvalid : function(){
this.df.clearInvalid();
this.tf.clearInvalid();
} // eo function clearInvalid
// }}}

It restores functionality when calling clearInvalid which is done by form.reset() for example.

jsakalos
16 May 2008, 2:00 PM
abraxxa,

thank you, adding your patch (clearInvalid function) to the main code.

Cheers,
Saki

johnymutton
19 May 2008, 8:45 PM
Saki,

Thank you for all your hard work. Your examples and insight are very helpful to me as a new user to the Ext library.

I have been working with your datetime object and cannot determine how to write a renderer function for a datetime object in column model for an EditorGrid.

In the past I have used something along the lines of:



...
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
...
in a column model that is used by the EditorGrid when using a Ext.form.DateField object. Or I have written a renderer function such as:



...
renderer: renderDate,
...

function renderDate(value){
return value ? value.dateFormat('m/d/Y') : '';
};
What would be an equivalent way to create a renderer for a Ext.ux.form.DateTime object?

thank you

john

jsakalos
20 May 2008, 12:29 AM
Renderer is already there; it is part of the DateTime field (last function). You can either use it as it is (you need to pass column config into it) or you can use it as the model to write your own one.

johnymutton
20 May 2008, 8:57 AM
Renderer is already there; it is part of the DateTime field (last function). You can either use it as it is (you need to pass column config into it) or you can use it as the model to write your own one.

Saki,

I am sorry if this is a stupid question, but I can't figure out how I would use the renderer that is already there or write my own using the DateTime renderer as a starting point. I would really appreciate a few more details concerning this.

When trying to write my own renderer, I am not entirely sure how I would pass the column config into it. I can see that it requires a field variable which is a column config, and in that config it requires an editor param. When I write my own renderer for other column model items as in the following snippet, I see that value,meta,record,rowIndex,colIndex and store are passed automatically into the renderer. It is not clear to me how I would get the column config from these parameters or how I would pass the column config along with these parameters.



// column model
...
renderer: MyDateRender,
...

// Customer renderer function
function MyDateRender(value,meta,record,rowIndex,colIndex,store)
{
// not sure how to return the rendered value from DateTime here
...
return value;
}
When I try to use the renderer included in DateTime rather than write my own renderer and pass in a column model config like so:



...
renderer: new Ext.ux.form.DateTime({dataIndex: 'StartTime', editor: new Ext.ux.form.DateTime()}),
editor: new Ext.ux.form.DateTime({
timeFormat:'H:i'
,timeConfig: {
altFormats:'H:i'
,allowBlank:true
}
,dateFormat:'d.n.Y'
,dateConfig: {
altFormats:'Y-m-d|Y-n-d'
,allowBlank:true
}
}),
...
I get an error



c.renderer is not a function
doRender([Object name=JNumber id=0 style=width:93px;, Object name=DOB id=1 style=width:68px;, Object name=RoomNum id=2 style=width:68px;, 12 more...], [Object id=1 data=Object json=Object store=Object fields=[23], Object id=2 data=Object json=Object store=Object fields=[23], Object id=3 data=Object json=Object store=Object fields=[23], 2 more...], Object data=[5] baseParams=Object paramNames=Object, 0, 15, true)ext-all-debug.js (line 30178)
renderRows(0, 4)ext-all-debug.js (line 30645)
renderBody()ext-all-debug.js (line 30649)
refresh(undefined)ext-all-debug.js (line 30673)
onDataChange()ext-all-debug.js (line 30812)
fire()ext-all-debug.js (line 1488)
fireEvent()ext-all-debug.js (line 1184)
loadRecords(Object success=true records=[5] totalRecords=5, Object, true)ext-all-debug.js (line 10652)
loadResponse(Object params=Object request=Object reader=Object, true, Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 11139)
apply(function(), Object events=Object conn=Object useAjax=true, [Object params=Object request=Object reader=Object, true, Object tId=1 status=200 statusText=OK], undefined)ext-base.js (line 9)
handleResponse(Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 5136)
getViewWidth(Object conn=XMLHttpRequest tId=1, Object scope=Object argument=Object timeout=30000, undefined)ext-base.js (line 10)
getViewWidth()ext-base.js (line 10)

chrome://firebug/content/blank.gif p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
Thank you for reading this and thank you for any help you might be able to give me.

john

jsakalos
20 May 2008, 2:22 PM
Simplest is:



renderer:function(val) {
return Ext.util.Format.date(val, 'your date + time format, e.g. Y-m-d H:i:s');
}

johnymutton
21 May 2008, 10:54 AM
Simplest is:



renderer:function(val) {
return Ext.util.Format.date(val, 'your date + time format, e.g. Y-m-d H:i:s');
}


Thank you!!!!

that worked perfectly!! I thought I had tried that before, but I was trying many different combinations of code and must have gotten mixed up.

thank you again!

john

vcastel
22 May 2008, 5:44 AM
Is there any official DateTime.js for V2.1 ?

Until now, I was using "Ext.ux.form.DateTime.js 11 2008-02-22 17:13:52Z" and all works fine

I'm experiencing weird behaviour since we've update extjs to 2.1 ...
when I'm picking a date, the day is overwritten by the year and the year stays
if I pick the 3rd of september '08, in the field I've got '08/09/08' instead of '03/09/08' (french way)
if I write '10/05/22' in the field when I quit the field for an other, it's converted in '22/05/22'
and I can't write or choose any hour:minutes, it's overwrite with '00:00'


var fieldDelai = new Ext.ux.form.DateTime({
id : 'Delai',
timePosition : 'right',
timeFormat : 'H:i',
timeConfig : {
altFormats : 'Hi',
allowBlank : true
},
dateFormat : 'd/m/y',
dateConfig : {
altFormats : 'd/m/Y',
allowBlank : true
},
name : 'Delai',
width : 120
});

any idea ?
(everything else (combo box, tree, fields, ...) are working fine)

Edit : to be complete, I must add that I'm using the last version of DateTime I have found ( Ext.ux.form.DateTime.js 264 2008-05-16 22:05:36Z)

lobo-tuerto
22 May 2008, 7:52 AM
@vcastel:
There is a fix for it in the subversion repository. Or you could go back to 2.0 while they push the fix into mainstream.

@saki:
For some reason the timefield error message is the only one that isn't getting localized, datefield is, as all my other form fields in my form. Any ideas?

mystix
22 May 2008, 9:26 AM
I'm experiencing weird behaviour since we've update extjs to 2.1 ...

try the override in this thread:
http://extjs.com/forum/showthread.php?t=33112

jsakalos
22 May 2008, 1:32 PM
@saki:
For some reason the timefield error message is the only one that isn't getting localized, datefield is, as all my other form fields in my form. Any ideas?

Hmmm, I'm not doing anything with error messages in the extension. Do you override standard TimeField messages to localize?

Or, have you tried standard TimeField? Does it also experience problems?

vcastel
22 May 2008, 11:08 PM
@vcastel:
There is a fix for it in the subversion repository. Or you could go back to 2.0 while they push the fix into mainstream.



try the override in this thread:
http://extjs.com/forum/showthread.php?t=33112

Thanks a lot, both of you !

the override solved my problem !

jcwatson11
23 May 2008, 4:18 AM
Hi Saki,

I'm using your RowActions and RecordForm extensions and may have need of this datetime field also... Would this datetimefield be compatable with those in a grid setup?

Jon

jsakalos
23 May 2008, 8:28 AM
Yes, I use it as grid editor. No problems.

jcwatson11
23 May 2008, 9:20 AM
Yes, I use it as grid editor. No problems.

Okay, Thanks. And Thanks especially for the thoughtful contributions on your website. You are a huge asset to the community!

jcwatson11
23 May 2008, 12:50 PM
Hi Saki,

Okay, I just read through this monolithic thread... looks like you already tackled all the grid issues. But I'm trying to figure out how you intend the existing column renderer to be used. Along those lines, perhaps you could put together an example page that uses this field in both a form and in a grid? It appears that your website links back to this thread and there is no example. I hope that's not too much to ask, my friend... and if it's not too much, perhaps you could provide an example of how you would use your renderer in its current form passing a column config into it?

Thanks again for all your help!

jsakalos
23 May 2008, 1:01 PM
The story if built-in renderer is simple. I use my (unpublished) extension of grid MetaGrid, that is configured from the server. That MetaGrid makes use of the build in renderer automatically providing the necessary argument field that is ColumnModel.config[xy] in fact. If you would want to use the built-in renderer outside the MetaGrid, you'd need to supply this argument.

I would say that it is simpler just to use renderer I've posted a couple of posts back. The only advantage of the built-in one is that it checks dateFormat and timeFormat of the field and uses them that is important only for multilingual applications.

lobo-tuerto
23 May 2008, 1:58 PM
@saki:

In effect, the original error messages from TimeField aren't localized. Where can I report this?

jsakalos
23 May 2008, 2:37 PM
Make sure it is really a bug and post then to Bugs forum.

lobo-tuerto
23 May 2008, 3:24 PM
Well, the datefield by its side has the error message localized, but the timefield doesn't.

When I put just a timefield instead of a datetime, all the other form fields have localized messages, except the timefield. Going to check it carefully though.

BTW this is for the spanish translation.

jsakalos
23 May 2008, 3:40 PM
Find out if it is TimeField bug or Spanish locale file bug.

jcwatson11
23 May 2008, 4:54 PM
I use my (unpublished) extension of grid MetaGrid, that is configured from the server.

Any chance you might publish MetaGrid?

I have my own solution which uses grid definitions stored in a database table to auto-generate a JSON config for an editorgrid. Its a single PHP file that generates a unique JSON config object for any grid I need with xtype:"editorgrid". These grid objects get dynamically loaded into a tabpanel after retrieving it through an Ajax request.

The only problem with this approach is that a formal instance of the column model doesn't exist at config time. So I can't call any functions on the column model. In fact, the datetime renderer itself is defined inside the config object for the column model, inside the grid config object.

Since I know you were the original pioneer with regard to dynamic grid loading, I'm sure you have a solution. And had hoped it might have fewer limitations than the one I came up with.

So I'm very interested to see your approach to the matter since you must obviously have a formal instance of the column model when the grid loads. Perhaps you have a different way of loading the grid that allows you to do some pre-scripting to create formal instances of things like column models, etc. before processing the JSON object?

cvieira
23 May 2008, 7:47 PM
Hi,

It seems to be a problem if we have editable: true on time field. If we double click time field, that value will be the only value that we can get from the fields... ie if we double click time, it shows current time, and no matter value we put on later, the field.dateValue.dateFormat('Y-m-d H:i') will allways return current time, and not the one we chose.

Can you reproduce this? Do you know why this happens?

Thanks
Regards
Carlos

jsakalos
23 May 2008, 11:44 PM
@jcwatson11,

no, I've decided that I won't publish my MetaGrid. The main reason is that it is too tightly bound to my server side infrastructure and I do not have time to mend it to be universal enough for public.

Re column model: just specify a dummy column model: new Ext.grid.ColumnModel([{header:''}]); - it will be replaced when meta is received from server.

jsakalos
23 May 2008, 11:48 PM
@cviera,

DateTime is for date and time. If you need only time you had better is to use TimeField. DateTime has config option emptyToNow and otherToNow config options:


/**
* @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
*/
,otherToNow:true
/**
* @cfg {Boolean} emptyToNow Set field value to now on attempt to set empty value.
* If it is true then setValue() sets value of field to current date and time (defaults to false)
*/

cvieira
25 May 2008, 7:32 AM
@jsakalos, thanks for the help :)

Now i have another problem... in IE6 and IE7.

I can get the correct value from DateTime field, if the field looses focus.
For example, i choose a date and time (selected from the combo or written), and then i click the button to submit the form. The value that i get with field.dateValue.dateFormat('Y-m-d H:i') on submitting, is not the value that i inserted, but the current date and time...

I can get only the value that i inserted/edit, if before submitting the form, i click elsewhere in the form (datetime field looses focus)... any idea of what is happening? In Firefox works fine.

berend
26 May 2008, 9:43 PM
Does anyone have a link to the latest version of this datetime control? I wrote something myself, but better to use something that might become official.

jsakalos
27 May 2008, 2:28 AM
First post of this thread contains the latest code.

lobo-tuerto
28 May 2008, 7:14 AM
Find out if it is TimeField bug or Spanish locale file bug.

The problem is the localized spanish language file, it lacks the translation for TimeField.

jsakalos
28 May 2008, 9:52 AM
Good. It's easy then - you can correct it and post it somewhere (Bugs?) so it finds its way to svn.

kevinwu8
2 Jun 2008, 11:09 PM
Hi..

I have a xtype's Grid, this grid have a handleAdd method that can open a form for user to add new data..
This form have a datetime field use Datetime Extension Class..
When add "store.load" code in xtype's Grid's onRender method..
And i run handleAdd method to open the new record form..
Whatever i click any time on Datetime Class... time field always show 00:00:00

If i remove "store.load" code in xtype's Grid's onRender method..
The time field show correct time that i click time field..

Would you help me ??



,onRender:function(){
myAp.wkmast.superclass.onRender.apply(this, arguments);
this.store.load({
params: {start: 0, limit: 20}
});
}// eo function onRender

,createComponent: function(){
this.store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '../PHP/wkmast.php'
}),
baseParams:{task:'read'},
reader:new Ext.data.JsonReader(
{
id:'sn_id',
root:'results',
totalProperty:'total',
fields: [
{name: 'sn_id', type: 'int'},
{name: 'wk_id', type: 'string'},
{name: 'status_id', type: 'string'},
{name: 'status_name', type: 'string'},
{name: 's_cate_id', type: 'string'},
{name: 's_cate_name', type: 'string'},
{name: 'a_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 's_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 'm_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 'f_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 'v_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 'c_time', type: 'date', dateFormat:'Y-m-d H:i:s'},
{name: 'a_descr', type: 'string'},
{name: 'a_uid', type: 'string'},
{name: 'a_uname', type: 'string'},
{name: 'r_uid', type: 'string'},
{name: 'r_uname', type: 'string'},
{name: 'a_dptid', type: 'string'},
{name: 'a_dptname', type: 'string'},
{name: 'a_telno_1', type: 'string'},
{name: 'a_telno_2', type: 'string'},
{name: 'eqp_uid', type: 'string'},
{name: 'eqp_uname', type: 'string'},
{name: 'eqp_id', type: 'string'},
{name: 'eqp_name', type: 'string'},
{name: 'eqp_uid', type: 'string'},
{name: 'eqp_uname', type: 'string'},
{name: 'eqp_id', type: 'string'},
{name: 'eqp_name', type: 'string'},
{name: 'eqp_uid', type: 'string'},
{name: 'eqp_uname', type: 'string'},
{name: 'p_dptid', type: 'string'},
{name: 'p_dptname', type: 'string'},
{name: 'p_uid', type: 'string'},
{name: 'p_uname', type: 'string'},
{name: 'p_descr', type: 'string'},
{name: 'p_hr', type: 'float'}
]

}),
remoteSort:true,
sortInfo:{field:'sn_id',direction:'ASC'}
});//end of ds
var sm = new Ext.grid.RowSelectionModel();
this.cm = new Ext.grid.ColumnModel([
{header:'序號',dataIndex:'sn_id',hidden:true,sortable:false},
{header:'單據編號',dataIndex:'wk_id',width:18,sortable:true},
{header:'送修單位',dataIndex:'a_dptname',width:18,sortable:true},
{header:'型號/機號',dataIndex:'eqp_name',width:50,sortable:true},
{header:'送修說明',dataIndex:'a_descr',width:40},
{header:'狀態',dataIndex:'status_name',width:10,sortable:true},
{header:'送修時間',dataIndex:'a_time',width:30,renderer: Ext.util.Format.formatDate,sortable:true},
{header:'送修人',dataIndex:'a_uname',width:20,sortable:true}
]);//end of cm
this.cm.defaultSortable = true;
this.selModel = sm;
this.store.setDefaultSort('sn_id', 'desc');
this.tbar = new Ext.Toolbar({
items:[
{
text: '新增',
tooltip: '新增送修單',
handler: this.handleAdd,
scope: this,//有加這一個Scope,handler所呼叫的Public Method才會有this Object..
iconCls:'add'
}
]
});
}//end of createComponent

,handleAdd:function(){
addForm = new myAp.MyForm({
id: 'AddwkmastForm'
});//end of addForm
var tabId = 'addWkmastTab';
var tabTitle = '新增叫修單';
var CenterPanel = Ext.getCmp('center');
tab = CenterPanel.getItem(tabId);
if(!tab){
CenterPanel.add({id:tabId,title:tabTitle,autoScroll:false,layout:'fit',items:[addForm]});
CenterPanel.show();//CenterPanel.show會啟動Empform.render()
}
tab = CenterPanel.getItem(tabId);
CenterPanel.setActiveTab(tab);//把新增加的TabAvtive起來
}//end of handleAdd

jsakalos
3 Jun 2008, 12:43 AM
I don't know how MyForm looks like. Nevertheless, you're creating new form with same id
'AddwkmastForm' over and over on each click. That cannot work.

kevinwu8
3 Jun 2008, 1:10 AM
Dear Jsakalos..

Here is MyForm look like..



Ext.ns('myAp');
myAp.MyForm = function(config) {
myAp.MyForm.superclass.constructor.call(this, config);
}
Ext.extend(myAp.MyForm,Ext.form.FormPanel, {
frame:true
,labelWidth:100
,id:'form'
,url:'.'
,initComponent: function(){
Ext.apply(this, {
items:[{
xtype:'xdatetime'
,id:'dtf'
,fieldLabel:'Date & Time'
,anchor:'-18'
,timeFormat:'H:i:s'
,timeConfig: {
altFormats:'H:i:s'
,allowBlank:true
}
,dateFormat:'d.n.Y'
,dateConfig: {
altFormats:'Y-m-d|Y-n-d'
,allowBlank:true
}
}]//end of items
}); // e/o apply
myAp.MyForm.superclass.initComponent.apply(this, arguments);
}//end of initComponent

,onRender:function(){
myAp.MyForm.superclass.onRender.apply(this, arguments);
}// eo function onRender
});// e/o extend
//Register xtype
Ext.reg('x-MyForm', myAp.MyForm);
And even if i remove the form id:'AddwkmastForm', the time field still show '00:00:00'..



,handleAdd:function(){
var wkmastGrid = this;
var sm = this.selModel;

addForm = new myAp.MyForm({});//end of addForm
addForm.addButton({
text: '儲存',
formBind:true,
handler:function(){
addForm.form.submit({
url:'../PHP/wkmast.php', // URL to send your username & password variables to
params:{task:'create'},
waitTitle:'Connecting',
waitMsg: '資料儲存中...',
scope:this,
success: function(form, action) {
var responseData = Ext.util.JSON.decode(action.response.responseText); //passed back from server

//Extract the ID provided by the server
var wk_id = responseData.newID;

Ext.Msg.alert('狀態','送修資料儲存成功!! 單據編號為:'+wk_id);//{success:true, newID:$wk_id}
CenterPanel = Ext.getCmp('center');
ActiveTab = CenterPanel.getActiveTab();

CenterPanel.remove(ActiveTab); //移除目前新增加的Edit FormPanel
CenterPanel.setActiveTab(CenterPanel.items.getCount() - 1);//好像有跟沒有一樣都惠setActiveTab前一個Tab

addForm.form.reset();
wkmastGrid.handleRefresh();
},
failure: function() {
Ext.Msg.alert('狀態','送修資料寫入失敗,請檢查您輸入的資料是否有問題!!');
}
}); //end of form.submit
}//end of handleSubmit
});//end of addButton

addForm.addButton({
text: '取消',
handler:function(){
CenterPanel = Ext.getCmp('center');
ActiveTab = CenterPanel.getActiveTab();
CenterPanel.remove(ActiveTab);
CenterPanel.setActiveTab(CenterPanel.items.getCount() - 1);//好像有跟沒有一樣都惠setActiveTab前一個Tab
}//end of handleSubmit
});//end of addButton

//addForm.startMonitoring(); //startMonitoring Method可以Monitor Form,當Form的值都Valid時Submit才會Enable..

var tabId = 'addWkmastTab';
var tabTitle = '新增叫修單';
var CenterPanel = Ext.getCmp('center');
tab = CenterPanel.getItem(tabId);
if(!tab){
CenterPanel.add({id:tabId,title:tabTitle,autoScroll:false,layout:'fit',items:[addForm]});
CenterPanel.show();//CenterPanel.show會啟動Empform.render()
}
tab = CenterPanel.getItem(tabId);
CenterPanel.setActiveTab(tab);//把新增加的TabAvtive起來

//en of init default value to addForm
}//end of handleAdd
I have try remove code "this.store.load({params: { start: 0,limit: 20}});" from x-type Grid's onRender...
And timefiled will show correct...

Help me please...Thx

jsakalos
3 Jun 2008, 1:18 AM
I see. Anyway, do you think it is DateTime related or that it is a bug in DateTime? If so, please prepare a simplified showcase that I can debug locally and that shows the issue.

kevinwu8
3 Jun 2008, 1:48 AM
Yes...Jsakalos...

My simplified showcase is over here..
First code is my x-type grid..name is x-wkmast...



Ext.ns('myAp');
myAp.wkmast = function(config) {
myAp.wkmast.superclass.constructor.call(this, config);
}
Ext.extend(myAp.wkmast,Ext.grid.GridPanel, {
loadMask: true
,loadMask:{msg:'Data Loading...'}
,iconCls: 'icon-grid'
,viewConfig:{forceFit:true
,emptyText:'No Data Display..'
}
,autoScroll: true
,onRender:function(){
myAp.wkmast.superclass.onRender.apply(this, arguments);
this.store.load({params: { start: 0,limit: 20}});
}// end of function onRender

,initComponent: function(){
this.createComponent();
Ext.apply(this, {}); // e/o apply
myAp.wkmast.superclass.initComponent.call(this);
}//end of initComponent

,createComponent: function(){
this.store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '../PHP/wkmast.php'
}),
baseParams:{task:'read'},
reader:new Ext.data.JsonReader(
{
id:'sn_id',
root:'results',
totalProperty:'total',
fields: [
{name: 'sn_id', type: 'int'},
{name: 'a_time', type: 'date', dateFormat:'Y-m-d H:i:s'}
]
}),
remoteSort:true,
sortInfo:{field:'sn_id',direction:'ASC'}
});//end of ds

var sm = new Ext.grid.RowSelectionModel(/*{singleSelect:true}*/);
this.cm = new Ext.grid.ColumnModel([
{header:'SN',dataIndex:'sn_id',hidden:true,sortable:false},
{header:'A Time',dataIndex:'a_time',width:30,sortable:true}
]);//end of cm
this.cm.defaultSortable = true;
this.selModel = sm;
this.store.setDefaultSort('sn_id', 'desc');
this.tbar = new Ext.Toolbar({
items:[{
text: 'Add',
tooltip: 'Add new record',
handler: this.handleAdd,
scope: this,
iconCls:'add'
}]
}); //end of tbar
}//end of createComponent

,handleAdd:function(){
addForm = new myAp.MyForm({});//end of addForm
addForm.addButton({
text: 'Save',
formBind:true
});//end of addButton

addForm.addButton({
text: 'Cancel'
});//end of addButton

var tabId = 'addWkmastTab';
var tabTitle = 'Add New Record Form';
var CenterPanel = Ext.getCmp('center');
tab = CenterPanel.getItem(tabId);
if(!tab){
CenterPanel.add({id:tabId,title:tabTitle,autoScroll:false,layout:'fit',items:[addForm]});
CenterPanel.show();
}
tab = CenterPanel.getItem(tabId);
CenterPanel.setActiveTab(tab);
}//end of handleAdd Function
});//end of extend x-wkmast grid
//Register x-wkmast xtype
Ext.reg('x-wkmast', myAp.wkmast);
second code is x-type MyForm that contain a xdatetime field...



Ext.extend(myAp.MyForm,Ext.form.FormPanel, {
frame:true
,labelWidth:100
,url:'.'
,initComponent: function(){
Ext.apply(this, {
items:[{
xtype:'xdatetime'
,id:'a_time'
,fieldLabel:'A Time'
,anchor:'-18'
,timeFormat:'H:i:s'
,timeConfig: {
altFormats:'H:i:s'
,allowBlank:true
}
,dateFormat:'d.n.Y'
,dateConfig: {
altFormats:'Y-m-d|Y-n-d'
,allowBlank:true
}
}]//end of items
}); // e/o apply
myAp.MyForm.superclass.initComponent.apply(this, arguments);
}//end of initComponent

,onRender:function(){
myAp.MyForm.superclass.onRender.apply(this, arguments);
}// eo function onRender
});// e/o extend
//Register xtype
Ext.reg('x-MyForm', myAp.MyForm);
I open the x-wkmast on center tab panel when i click the tree..


Please help me..
thank you very much...

jsakalos
3 Jun 2008, 2:57 AM
How would I run it? Where's onReady?

kevinwu8
3 Jun 2008, 5:35 AM
Dear Jsakalos..

I run x-wkmast grid use this code..

index.html


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="../extjs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../extjs/ext-all.js"></script>
<script type="text/javascript" src="../js/ux/TabCloseMenu/TabCloseMenu.js"></script>
<script type="text/javascript" src="../js/ux/DateTime/DateTime.js"></script>
<script type="text/javascript" src="../js/ux/miframe/miframe-min.js"></script>
<script type="text/javascript" src="../js/myAp/MyForm.js"></script>
<script type="text/javascript" src="../js/wkmast.js"></script>
<link rel="stylesheet" type="text/css" href="../styles/tabs-example.css" />
<link rel="stylesheet" type="text/css" href="../styles/grid-examples.css" />
<link rel="stylesheet" type="text/css" href="../styles/forms.css" />
<link rel="stylesheet" type="text/css" href="../styles/examples.css" />
<style type="text/css">
html, body {
font:normal 12px verdana;
margin:0;
padding:0;
border:0 none;
overflow:hidden;
height:100%;
}
</style>

<script type="text/javascript">
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
Ext.namespace('myAp');
myAp.main = function(){
var myLayout;
var NorthPanel;
var SouthPanel;
var WestPanel;
var CenterPanel
var myViewport;
//private functions :
var defineLayout = function(){
NorthPanel = new Ext.Panel({
region:'north',
contentEl:'north',
title: 'North Panel',
split:false,
height:50,
collapsible:false,
margins:'0 0 0 0'
});
SouthPanel = new Ext.Panel({
region:'south',
split:false,
title: 'South Panel',
height: 25,
collapsible: false,
margins:'0 0 0 0'
});
WestPanel = new Ext.Panel({
region:'west',
id:'west-panel',
title:'West Panel',
split:true,
border: true,
collapseFirst: true,
collapsible : true,
collapsed:false,
width: 200,
minSize: 175,
maxSize: 400,
collapsible: true,
margins:'0 0 0 0',
layout:'accordion',
defaultType:'iframepanel',
defaults:{
loadMask:false,
bwrapStyle:{position:'absolute'},
hideMode: Ext.isGecko?'visibility':'display'
},
layoutConfig:{
animate:true
}
});
CenterPanel = new Ext.TabPanel({
id:'center',
region:'center',
deferredRender:false,
activeTab:0,
resizeTabs:false,
minTabWidth: 115,
tabWidth:135,
enableTabScroll:true,
autoDestroy:false,
bodyBorder:false,
layoutOnTabChange:true,
defaultType: 'iframepanel',
defaults:{
iconCls:'tabs',
closable:true,
autoShow:true,
bodyStyle:{width:'100%',height:'100%'},
margins:'0 0 0 0',
maskEl:'bwrap'
},
items:[{
xtype:'x-wkmast',
title: 'WKMast Grid'
}],
plugins: new Ext.ux.TabCloseMenu()//Plugin a Ext.ux
});
myViewport = new Ext.Viewport({
layout:'border',
items:[NorthPanel, SouthPanel, WestPanel, CenterPanel]
});
};
return{
init:function(){
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'under';
this.doLayout();
},
doLayout:function(){
defineLayout();
}
};
}();
Ext.onReady(myAp.main.init,myAp.main,true);
</script>
</head>
<body>
<div id="north">
</div>
<div id="west"></div>
<div id="center"></div>
<div id="props-panel" style="width:200px;height:200px;overflow:hidden;"></div>
<div id="south"></div>
</body>
</html>

jsakalos
3 Jun 2008, 6:07 AM
Hmm, I have meant a simplified showcase - this all would mean that I need to setup whole your application locally.

First of all, make sure that it is a bug in my extension (I have no time to debug aplications). If you are sure it is a bug in extension then post simpleshowcase so that I can isolate and fix the bug fast.

kevinwu8
3 Jun 2008, 6:22 AM
Dear Jsakalos..

This code is my simplest showcase i can provide...Sorry...

In my application's x-grid extension, if i load ds at grid's onRender method..
the DateTime extension's time field alway show '00:00:00' whatever i click any time...
But date field display correct...Only time field display not correct..

So i think problem mybe is DateTime extension's time field...or maybe other...

many thank you time to reply me..
and sorry my pool english..
wish you can give me more advise to resolve this problem ..

jsakalos
3 Jun 2008, 6:38 AM
I'm using same DateTimeField in my application and I've never seen 0-time-problem so please dig further to find the root of it. If it's DateTime then let me know.

kevinwu8
3 Jun 2008, 7:45 AM
Dear Saki...

I have modifed the extjs's array-grid example that have a add button to show this problem...
Please unzip the 'grid.zip' attached file in extjs\examples\grid folder..
And run array-grid.html file..

click add button to display a new form..
Try to click any time in timefield...you will see the timefield's problem..

jsakalos
3 Jun 2008, 2:11 PM
I've tested it, however, I removed examples.js script as unnecessary, and I haven't found any problem. I can select any time from the list and the time field is initially blank, not zero.

The only remaining thing that can be different is the version of Ext. I use latest svn.

kevinwu8
3 Jun 2008, 4:32 PM
Dear Saki...

Many thanks to you and my extjs version is 2.1.0 (rev 2042)...
I have not lastest svn extjs...
Would you please test again use this version's extjs to make sure...

Hope you can give some advise to me.

Thanks again..

nebbian
3 Jun 2008, 7:04 PM
Hi Saki,

I'm having exactly the same problem. If I just use your example code then there's no problem, but if I bind the field to some data inside a ux.grid.RecordForm, then it remains at 12:00 after clicking. If the data already in the field has a proper time in it then this shows initially.

It looks to me like a validation thing? I'm still trying to figure it out.

jsakalos
4 Jun 2008, 12:57 AM
Post please a showcase; i cannot fix it until I see it.

kevinwu8
4 Jun 2008, 3:22 AM
Dear Saki...

If my issue's cause is difference extjs version...
Would you please help me solve this problem...

jsakalos
4 Jun 2008, 5:15 AM
Search please the forums, I have a feeling that I've read something about TimeField in version 2.1. Maybe there is a patch too...

kevinwu8
4 Jun 2008, 7:53 AM
Hi.Saki...

I have fixed this issue follow this post..
http://extjs.com/forum/showthread.php?t=33112

many thanks to you..

nebbian
4 Jun 2008, 6:19 PM
Post please a showcase; i cannot fix it until I see it.



Hi.Saki...

I have fixed this issue follow this post..
http://extjs.com/forum/showthread.php?t=33112

many thanks to you..

Hi Saki, following the above link fixed the problem :D

Many thanks kevinwu8 =D>

ttony
6 Jun 2008, 10:26 AM
There seems to be an a rendering error with the DateTime plugin. When I Show/Hide the FormPanel that contains this plugin, it renders like this. When I change the FormPanel to hideMode: "offsets", the plugin renders fine but a new display error is introduced (in IE7 only). Please see attachments.

Does anyone know how to fix this or where the rendering problems are coming from?

IMAGES:
First image is IE7, second is FF2, third is IE7 using hideMode:"offsets"

ttony
6 Jun 2008, 10:56 AM
I found a fix:

Use the hideMode: "offsets", add formpanel.el.repaint() when showing the component

nbourdeau
9 Jun 2008, 12:03 PM
Try to set timeWidth or try to set some dimensions on their container or both. To fully understand the sizing take a look at setSize function; it is the simple one.


Hi,

I have the same problem but not rendering into something hidden. It's in a panel (in a tab panel) with a simple html table inside. I want to render the datetimefield in a table cell. But the date and time renders one over another. What should i do ? Can we use this extension in a standalone mode ?

jsakalos
9 Jun 2008, 3:44 PM
Do you have timePosition:'below'? If not, post a simplified showcase.

nbourdeau
10 Jun 2008, 7:26 AM
Do you have timePosition:'below'? If not, post a simplified showcase.

No, i want to have timePosition: 'right'. 'below' is working correctly ...

For example :



Html in the web page :
<table>
<tr><td>Some field :</td>
<td><input type='text'></td></tr>
<tr><td>Date field :</td>
<td><div id='df' /></td></tr>
</table>

Then extJs code :
var df = new Ext.ux.form.DateTime({
renderTo: 'df',
name: 'from',
timeFormat:'H:i',
timePosition: 'right',
timeConfig: { allowBlank:true },
dateFormat:'Y-m-d',
dateConfig: { allowBlank:false }
});



If i add timeWidth: '200' for exmaple, then the DateField widget gets larger but they are still one over another.

jhoni.chen
10 Jun 2008, 9:11 PM
Dear Saki...

Many thanks to you and my extjs version is 2.1.0 (rev 2042)...
I have not lastest svn extjs...
Would you please test again use this version's extjs to make sure...

Hope you can give some advise to me.

Thanks again..

Hi All,
I'm having the same problem (time fields always become 00:00:00). Finally I got it fix by adding some patches, check the override code at http://www.extjs.com/forum/showthread.php?t=33112

jsakalos
11 Jun 2008, 12:16 AM
Yes, it was Ext bug that is already fixed in svn, and it has nothing to do with this exception except it shows up also here.

Stefan B
11 Jun 2008, 5:51 AM
Hello Saki,

for submission of a dynamic form we need the submitted values to be restricted to exactly the values that are to be stored. So the question is:

Is there a way to prevent the "...-date" and "...-time" helper fields from being submitted with the form (i.e. from being included in form.getValues() in our case)?

In Combo.js, l. 309, it is done via the following code:

this.el.dom.removeAttribute('name');
I couldn't find a something similar in the DateTime code, although I'm not sure if a similar approach is applicable for DateTime at all.

Thanks for your support
Stefan

jsakalos
11 Jun 2008, 11:55 AM
Well, there is only one way to find out: to try ;) I always supposed that you can ignore these extra submission - if you cannot try the concept you suggest and I can patch the code then if it works.

Stefan B
11 Jun 2008, 10:58 PM
Okay, so you could add the bold code section to the onRender method:


// setup name for submit
this.el.dom.name = this.hiddenName || this.name || this.id;

// prevent helper fields from being submitted
this.df.el.dom.removeAttribute("name");
this.tf.el.dom.removeAttribute("name");

// we're rendered flag
this.isRendered = true;

Tested on FF 2.0.0.14, IE6, IE7, Opera 9.27, Safari 3.1.1 (Windows only)

jsakalos
12 Jun 2008, 1:05 PM
Thank you Stefan, adding...

Stefan B
13 Jun 2008, 2:39 AM
EDIT: Seems to be fixed by changes in latest SVN

Hello Saki,

thanks for incorporating the above addition to your code.

I think I have discovered a bug in the component:
If you add a predefined value to the fields config object like this:

,value: Date.parseDate("2008-06-13 11:00:00", "Y-m-d H:i:s")
the time value is not accepted and instead the time field shows 00:00:00

The thing I found out is that the time field's setValue method is called twice, once from the initial DateTime.setValue, the second time from the time field's own onRender handler. Thus the underlying value is parsed twice, resulting in an invalid date the second time.

Can you confirm this bug, and would you know how to work around it?

Thanks
Stefan

wuschba
13 Jun 2008, 3:27 AM
Greate code. I got only one problem:

A value, which the user inputs is correctly saved to the mysql-database, like:
2008-06-13 13:05:37

But putting this mysql-date-value into the field with form.load, I get strange results depending on the dateFormat:
04/06/80 1:19 PM with 'm/d/y'
29.11.18 1:19 PM with 'd.m.y'

Shouldn't the input be in the hiddenFormat-format as well?

Added:
I just found a fix, perhaps you might review it and include it to your code:


/**
* @param {Mixed} val Value to set
* Sets the value of this field
*/
,setValue:function(val) {
if(!val && true === this.emptyToNow) {
this.setValue(new Date());
return;
}
else if(!val) {
this.setDate('');
this.setTime('');
this.updateValue();
return;
}
var hiddenVal = Date.parseDate(val, this.hiddenFormat);
if (hiddenVal) val = hiddenVal;

if ('number' === typeof val) {
val = new Date(val);
}
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
var da, time;
if(val instanceof Date) {
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();
} // eo function setValue

Stefan B
13 Jun 2008, 5:24 AM
Never mind my bug report from post #213. I just tried the latest Ext revision from SVN and the problem seems to have gone away.

Regards
Stefan

nbourdeau
13 Jun 2008, 5:26 AM
No, i want to have timePosition: 'right'. 'below' is working correctly ...

For example :



Html in the web page :
<table>
<tr><td>Some field :</td>
<td><input type='text'></td></tr>
<tr><td>Date field :</td>
<td><div id='df' /></td></tr>
</table>

Then extJs code :
var df = new Ext.ux.form.DateTime({
renderTo: 'df',
name: 'from',
timeFormat:'H:i',
timePosition: 'right',
timeConfig: { allowBlank:true },
dateFormat:'Y-m-d',
dateConfig: { allowBlank:false }
});

If i add timeWidth: '200' for exmaple, then the DateField widget gets larger but they are still one over another.

Hello Saki,

Did you see this post ? Have an idea on how to resolve this ?

wuschba
13 Jun 2008, 7:10 AM
Perhaps I found another bug:
When using the datetime-field in a form with defaults: { width: '100%' }, you get the problem that the width is given as a string and not as a number. Therefore IE will crash in ext-all-debug.js in line 2717


this.dom.style.width = this.addUnits(width);

because width is calculated as


this.df.setSize(w - this.timeWidth - 4, h);
which then ends up in: "100%" - this.timeWidth - 4 which of course is NaN.

I made a small workaround:



setSize:function(w, h) {
if(!w || isNaN(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);
}
}
} // eo function setSize

jsakalos
14 Jun 2008, 5:03 AM
I'm not going to implement this workaround because it is an attempt to handle the user misconfiguration. API says that width is number.

BTW, if you need 100% width in forms, use anchoring.

wuschba
14 Jun 2008, 11:59 PM
You are right - never thought about this, because the API says that 'auto' should be a valid value as well since it is the default-value. So 'auto' is a string and will make the actual code crash, too.

Paul Middelkoop
16 Jun 2008, 1:23 AM
nbourdeau: I have the same problem.

A work around is to just show the tab which has the datetime field. It now has correct dimensions. After that hide the tab:



Ext.onReady(function() {
$('propertiesTab').addClassName('x-hide-display');
}


Comboboxes have a simular problem. If they are not visible on render, the error icon will appear in the field since the TriggerField got a size 0. I fixed this by calling comboField.syncSize() before validating.

Maybe this problem should be fixed on a lower level.

jsakalos
16 Jun 2008, 2:54 AM
Paul,

most likely you are trying to render to display:none containers. There have been a lot of discussion about this on forums - please search. There are also some examples at http://examples.extjs.eu that show how to correctly put components to inactive tabs.

sean.zhou
18 Jun 2008, 10:11 AM
It will be better if the milliseconds are set to zero from the datetime value. Here is the suggested implementation:



getValue:function() {
if (this.dateValue) {
// create new instance of date with milliseconds set to zero
return new Date(Math.round(this.dateValue.getTime()/1000)*1000);
}
return '';
}


Setting milliseconds to zero will allow detection of two same DateTime objects created at different occasions.

mystix
18 Jun 2008, 10:17 AM
@sean, there's a clearTime() method in the Date class:
http://extjs.com/docs/?class=Date&member=clearTime

i disagree with getValue() always clearing the time though -- will be better if it were configurable


Ext.override(Ext.ux.form.DateTime, {
getValue : function(clearTime) {
if (this.dateValue) {
// create new instance of date with milliseconds set to zero
return clearTime? this.dateValue.clearTime(true) : this.dateValue;
}
return '';
}
});

note: i've yet to play with the DateTime field, so what's above is merely a result of my daily ramblings...

sean.zhou
18 Jun 2008, 12:24 PM
mystix, it seems that clearTime() zeros the time; here we only want to zero the millisecond leaving minutes and hours unchanged. My suggestion of modifying getValue() is a hack, which only zeros the milliseconds from the return value, while the value inside of the xdatetime object does not change. Any better ways of fixing?

mystix
18 Jun 2008, 5:35 PM
ahh... now i see what you're trying to do.

i misinterpreted "two same DateTime objects created at different occasions" to mean two DateTime objects created on the same day.

i guess your override will have to do then, albeit with the Date object's setMilliseconds() method instead.

relix01
24 Jun 2008, 1:01 PM
Has anyone tested this in Firefox 3? It works perfectly for IE6/7 and Firefox2. When I click on the date button to add a date, the date window renders the complete screen and hides everything beneath it.

abraxxa
24 Jun 2008, 1:07 PM
Works fine for me in firefox 3.

relix01
24 Jun 2008, 1:11 PM
Thanks Abra,
Can you post an example of your configs? I've been using this for awhile now, but recently upgraded to ff3. My current is in a tabpanel.


var panel = new Ext.TabPanel(
{
width: 'auto',
renderTo: 'chart_toolbar',
//title: 'test',
//html: '<p>help me see the light</p>',
//baseCls:'x-plain',
//items: [{contentEl:'fusionchart', title: 'test tile'}],
tbar:
[
vendor_combobox,
'-',
chainedHostcombobox,
'-',
'Start Time',
{
xtype: 'xdatetime',
id: 'start_time',
fieldLabel: 'start_time',
anchor: '-18',
timeFormat: 'g:i:s a',
timePosition: 'right',
timeConfig:
{
altFormats: 'g:i:s a',
allowBlank: true,
minValue: '12:00:00 am'
},
dateFormat: 'd.n.Y',
dateConfig:
{
altFormats: 'Y-m-d|Y-n-d',
allowBlank: false,
minValue:'06.5.2008'
}
},
'-',
'End Time',
{
xtype: 'xdatetime',
id: 'end_time',
fieldLabel: 'Date & Time'
// ,width:360
,
timePosition: 'right',
anchor: '-18',
timeFormat: 'g:i:s a',
timeConfig:
{
altFormats: 'g:i:s a',
allowBlank: true
},
dateFormat: 'd.n.Y',
dateConfig:
{
altFormats: 'Y-m-d|Y-n-d',
allowBlank: false,
minValue: '06.5.2008'
}
},
'-',
{
text: 'Go',
iconCls: 'chart_generate',
tooltip: 'Click me to generate a new chart!',
handler: function() {}
}] );

abraxxa
25 Jun 2008, 12:20 AM
You're missing a } in the last row!
}]});
Use firebug to find such errors!
For me the form didn't even render without the }.

relix01
25 Jun 2008, 5:25 AM
Only if it was that simple. It was a C & P error not a code error. The error would have been much different like a blank page! Remember firefox will not display correctly with errors like that, so I would 'never' even gotten to the point of clicking the calendar button.

Here's the fix........

Declare the css value.

.x-date-picker {
width:175px;
}


Call this.


Ext.DatePicker.prototype.internalRender = true;

aacraig
29 Jun 2008, 1:40 AM
Only if it was that simple. It was a C & P error not a code error. The error would have been much different like a blank page! Remember firefox will not display correctly with errors like that, so I would 'never' even gotten to the point of clicking the calendar button.

Here's the fix........

Declare the css value.

.x-date-picker {
width:175px;
}


Call this.


Ext.DatePicker.prototype.internalRender = true;



I had the same rendering problems with FF3 until I realized I had missed an Ext update. When I installed the latest Ext code (2.1), everything rendered correctly.

aacraig
29 Jun 2008, 1:53 AM
Using the code in the first post, I've discovered two possible errors, which were causing the date field to render to narrow to display the date.

The two spots in the code that seemed strange to me are:



line: 84
,width:this.timeWidth


As we're in the date field constructor at this point, I'm wondering if it shouldn't be


line: 84
,width:this.dateWidth


Further down, the code is:


line: 421
this.df.setSize(w - this.timeWidth - 4, h);


Also here, I'm wondering if we should be subtracting dateWidth, not timeWidth.

Making that change and stepping through, I saw that the value of 'w' always was equal to the value of this.dateWidth, so I made this change:


line: 421
// this.df.setSize(w - this.dateWidth - 4, h);
this.df.setSize(this.dateWidth - 4, h);


Since there is no specific default setting for dateWidth, I also added this line


line: 33
,timeWidth: 100
,dateWidth:200


I don't know if I'm the only one to have this problem. It only came out when I create a new object and then inserted that into my form. Inserting a constructor object into a form's items did not provoke the problem. In other words:


var dtm = new Ext.ux.form.DateTime({...});

var frm = new Ext.FormPanel({
...
items: [dtm]
});


doesn't render correctly without my changes.



var frm = new Ext.FormPanel({
...
items: [{
xtype: 'xdatetime',
....
}]
});


Works with the original code and with my changes.

anjelika
30 Jun 2008, 2:43 AM
Hello,
Is there a way to force the time field to display values from a custom interval only?
I mean, I would like to let the customers select a time value between 9 AM and 20 PM, is that possible?
Thanks

jsakalos
30 Jun 2008, 3:33 AM
timeConfig property is passed to the underlying time field, if that helps.

marco76
3 Jul 2008, 9:11 AM
I have a small problem in rendering in IE7
If I have the datetime field and two htmleditors all inside fieldsets when the two htmleditors are visible the datetime field is hidden.
If I have the datetime field and only one htmleditor visible all works fine.
My code:


new Ext.FormPanel({
url:this.noCache(url_submit),
method:'POST',
fileUpload:true,
defaultType: 'textfield',
labelWidth:90,
autoScroll:true,
bodyStyle:'padding:5px 5px 0 5px',
id:'form-DOC_'+document_id,
border:false,
items: [
{
xtype:'fieldset',
checkboxToggle:true,
title: '$label',
autoHeight:true,
defaultType: 'textfield',
collapsed: true,
items :new Ext.ux.form.DateTime({
fieldLabel: '".$label."',
name:'data[DocumentoCampo][campo_id]',
value:'valore_date',
allowBlank:false,
readOnly:true,
timeFormat:'H:i',
timeConfig: {
altFormats:'H:i',
allowBlank:false,
value: '$valore_time',
readOnly:true
},
dateFormat:'d/m/Y',
dateConfig: {
altFormats:'Y-m-d|Y-n-d',
allowBlank:false,
value: '$valore_date',
readOnly:true
}
})
},
{
xtype:'fieldset',
checkboxToggle:true,
title: 'label',
autoHeight:true,
defaultType: 'textfield',
collapsed: true,
items :[
new Ext.ux.HTMLEditor({
width: 550,
height: 300,
styles: ['htmleditor.css'],
plugins: [new Ext.ux.HTMLEditorImage(),new Ext.ux.HtmlEditorWordPaste({})],
enableColors: true,
listeners: {
render: function(c) {

c.getToolbar().items.get('forecolor').destroy();
}
},
name:'data[DocumentoCampo][campo_id]',
fieldLabel:'labe',
value:'valore'
})
]} ,

{
xtype:'fieldset',
checkboxToggle:true,
title: 'label',
autoHeight:true,
defaultType: 'textfield',
collapsed: true,
items :[
new Ext.ux.HTMLEditor({
width: 550,
height: 300,
styles: ['htmleditor.css'],
plugins: [new Ext.ux.HTMLEditorImage(),new Ext.ux.HtmlEditorWordPaste({})],
enableColors: true,
listeners: {
render: function(c) {

c.getToolbar().items.get('forecolor').destroy();
}
},
name:'data[DocumentoCampo][campo_id]',
fieldLabel:'labe',
value:'valore'
})
]}

]
});

jsakalos
3 Jul 2008, 12:56 PM
1) remove doctype if any
2) do not render to hidden containers (display:none)

marco76
3 Jul 2008, 11:17 PM
Sorry but what means "dont render to hidden containers(display:none)"?

jsakalos
4 Jul 2008, 12:03 AM
Search please forums, there has been a looooooooooot of discussions about rendering into hidden containers. See also http://examples.extjs.eu

72
6 Jul 2008, 3:10 PM
Hi saki,

easy implemented readOnly property, so it is not possible to write down, only select ;) (the property only)

Source as an attachment. Implemented on version i downloaded today.

atascon
6 Jul 2008, 11:27 PM
Edit:
**deleted original post**

In IE7 I dont see the controls.

I debugged using IE development toolbar and select the DIV inside the table and the rectangle it shows is located at the top of the page - see attached screenshot.

Now in the DOM if I remove the class attribute or the id attribute on either the date div or the time div the datetime control appears back.

the code is pretty basic but I might be missing something:

Ext.BLANK_IMAGE_URL = '/ext-2.1/resources/images/default/s.gif';

//Ext.namespace('DAS');
//var DAS={};
SearchApp = function() {
var topPanel;
var panelDesc;
var panelPeriod;
var panelResults;

function createDesc(){
panelDesc = new Ext.form.FieldSet({
id:'panelDesc',
title:'Description',
//frame:true,
labelWidth:90,
defaults:{width:300},
autoHeight:true,
defaultType:'textfield',
items:[{
fieldLabel:'Job number',
name:'jobNum'
},{
fieldLabel:'Name',
name:'committeeName'
},{
fieldLabel:'Reference',
name:'reference'
},{
fieldLabel:'Location',
name:'location'
},{
fieldLabel:'Archive Name',
name:'archiveName'
}]
});
}

function createTop(){
topPanel = new Ext.Panel({
title:'S E A R C H',
layout:'column',
layoutConfig:{columns:3},
border:false,
autoHeight:true,
defaults: {},
items:[
panelDesc
,{
border:false,
items:[{
xtype:'combo',
name:'inCameraFilter',
displayField:'text',
mode:'local',
width:350,
editable:false,
//forceSelection:true,
store:new Ext.data.SimpleStore({
fields:['type', 'text'],
data:[
[0,'Search both in-camera and NOT in-camera recordings'],
[1,'Only search for in-camera recordings'],
[2,'Only search for NOT in-camera recordings']
]
})
},{
xtype:'checkbox',
boxLabel:'Only search for retained recordings',
selectOnFocus:true,
hideLabel:true
},{
xtype:'checkbox',
boxLabel:'Itemize sessions',
hideLabel:true
},{
id:'panelPeriod',
xtype:'fieldset',
title:'Search Period',
checkboxToggle:true,
collapsible:false,
autoHeight:true,
labelWidth:40,
defaults:{
width:280,
//format:'D, jS F, y \\T\\i\\m\\e: h:i:s A',
dateFormat:'D, jS F, y',
timeFormat:'h:i:s A',
validationEvent:false,
validateOnBlur:false
},
defaultType:'xdatetime',
items:[{
name:'startDate',
fieldLabel:'Start',
value:new Date()
},{
name:'endDate',
fieldLabel:'End',
value:new Date()
}],
listeners:{}
}]
},{
//region:'east',
border:false,
html:'',
width:300,
defaults:{minWidth:80},
items:[{
xtype:'button',
text:'Search',
height:60,
handler:function(){
//
}
},{
xtype:'button',
text:'Reset',
height:30,
handler:function(){
//
}
}]
}]
})
}
return {
init: function(){
Ext.QuickTips.init();
createDesc();
createTop();
topPanel.render('version2');
}
};
}();

Ext.onReady(SearchApp.init, SearchApp, {delay:1});


EDIT2:
Found the problem(?):
If I remove the autoHeight config from id='panelPeriod' the controls stay where they should on the page.
Problem then is the panel isnt sized properly. Im not sure why that should be.

Alfred

jsakalos
6 Jul 2008, 11:48 PM
The only purpose of these css classes is to allow finding elements. They do not change visual appearance at all.

atascon
7 Jul 2008, 12:29 AM
Thanks - yeh i realised this as I was going through the code so I reposted my problem - I thought I had it by the actions I was performing. Sorry about the red-herring there, Im kinda new to a lot of CSS and ExtJs in general.

ignatius
8 Jul 2008, 9:23 PM
I am using datetime in an editor grid, but when I click the cell to edit, it picks up the date value correctly BUT not the time -time is always set to 00:00:00 GMT+1000 - no matter what the original date time value of the grid record is.

I don't have a simple example at the moment, but a console log of the object passed by the focus event on the cell column editor gives me this:
<snip>
e.originalValue =
e.dateValue = Mon Jun 30 2008 00:00:00 GMT+1000
e.hasFocus = true
e.startValue = Mon Jun 30 2008 00:00:00 GMT+1000
</snip>

The grid record data is 30/06/2008 12:45am - which is the rendered display of a datetime value in the form Y-m-d H:i: s.

Is there a trick to getting the timefield to populate correctly?
Another quirk... if the grid record data time is 00:00 (e.g. 2008-06-30 00:00:00), the timefield always comes up blank.

jsakalos
8 Jul 2008, 9:47 PM
I use DateTime in EditorGrids extensively and I don't have any of problems you describe. Double check your configuration please.

ignatius
8 Jul 2008, 10:01 PM
Here's my config:


editor:new Ext.ux.form.DateTime({
name: 'dtend'
,width:100
,allowBlank:false
,otherToNow:false
,emptyToNow:false
,timePosition:'below'
,dateFormat:'d/m/Y'
,dateWidth:80
,dateConfig:{
allowBlank:false
,altFormats:'Y-m-d'
}
,timeFormat:'g:ia'
,timeWidth:60
,timeConfig:{
allowBlank:false
,altFormats:'H:i|Hi|g:iA'
}
})


The grid column config is:


header:'Finish Date/Time'
,width:100
,sortable:true
,dataIndex:'dtend'
,dateFormat:'timestamp'
,renderer:this.RenderDateTime
...


The json data passed back from the store is in the format 'Y-m-d H:i: s' (no space between : s)

The renderer displays the date as d/m/Y g:ia.
IF I turn the renderer off, the timefield is populated correctly...

What am I missing?

jsakalos
8 Jul 2008, 10:04 PM
DateTime already contains renderer for grids. See the last method in the source code.

ignatius
8 Jul 2008, 10:16 PM
Have you got an example of how that would be used?

BTW, after staring at this for a day, I just figured out what the problem was... stupid me...
altFormat for time needs to include H:i: s - which is what the source data is.

wuschba
9 Jul 2008, 6:49 AM
Hi, I got another problem: When using the DateTime-Class on a FormPanel in IE7, I got this result (see picture). After collapsing the panel once, it's okay again.

To show the problem, I modified the code from the panel-example /jsext/examples/panel/panels.html to:



Ext.onReady(function(){
var p = new Ext.FormPanel({
title: 'My Panel',
collapsible: true,
collapsed: false,
renderTo: 'container',
autoHeight: true,
labelWidth: 140,
defaultType: 'textfield',
items: [{
fieldLabel: 'hello',
name: 'inputfield',
value: 'Some text here'
},
{ xtype: 'xdatetime',
fieldLabel: 'A datetime here',
name: 'datetimefield'
}
]

});
});


Any ideas about that?

jsakalos
9 Jul 2008, 2:56 PM
Do you use a doctype? Remove it if yes.

jsakalos
9 Jul 2008, 2:58 PM
Have you got an example of how that would be used?

BTW, after staring at this for a day, I just figured out what the problem was... stupid me...
altFormat for time needs to include H:i: s - which is what the source data is.

renderer function of DateTime field returns renderer that can be used in column model. Just look at the source, it's very simple.