PDA

View Full Version : [FIXED][3.??] isDirty will fail until Field is not rendered



sudden_def
22 Apr 2009, 11:11 PM
BasicForm.isDirty() may return true when using a tabbed form with deferredRender: true. This happens because Ext.form.Field's originalValue property will be initialized only after it'll be rendered.

The following code could fix the issue:


Ext.override(Ext.form.Field, {
isDirty : function() {
if(this.disabled || ! this.rendered) {
return false;
}
return String(this.getValue()) !== String(this.originalValue);
},
});

aconran
6 May 2009, 7:26 AM
Fixed in Ext 2.x and Ext 3.x.

mystix
6 May 2009, 7:52 PM
i think we need to revisit this fix.

a Field's originalValue should not be affected by its rendered state.
it should always be set on instantiation (i.e. somewhere in initComponent()), not onRender().

in long tabbed forms, it doesn't make sense for unrendered Fields (in unrendered tabs) which are modified by some action in a rendered tab to return isDirty() = false.

Condor
6 May 2009, 10:34 PM
I would agree, but you forgot one detail:
For fields created with 'el' or 'applyTo' the value (and the originalValue) are only known after render and not in initComponent.

sudden_def
6 May 2009, 10:42 PM
Again, there are custom componets based on Ext.form.Field class that are loading it's initial value dynamically (i.e. via AJAX request). This will cause originalValue field to be undefined nevertheless the field has an initial value.

Condor
6 May 2009, 11:17 PM
How about:

Ext.override(Ext.form.Field, {
initComponent: function(){
Ext.form.Field.superclass.initComponent.call(this);
if(this.originalValue === undefined){
this.originalValue = this.value;
}
},
initValue : function(){
if(this.value !== undefined){
this.setValue(this.value);
}else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
this.setValue(this.el.dom.value);
}
//this.originalValue = this.getValue();
},
setValue : function(v){
this.value = v;
if(this.rendered){
this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
this.validate();
}
if(this.originalValue === undefined){
this.originalValue = this.getValue();
}
return this;
},
isDirty : function() {
if(this.disabled /*|| !this.rendered*/) {
return false;
}
return String(this.getValue()) !== String(this.originalValue);
}
});
(not backward compatible if a field value actually contains 'undefined')

mystix
6 May 2009, 11:19 PM
I would agree, but you forgot one detail:
For fields created with 'el' or 'applyTo' the value (and the originalValue) are only known after render and not in initComponent.
good point.

we'll need to have separate handling for Fields created using 'applyTo' / 'el' then -- this would use the existing !rendered check, while dynamically created Fields would need to have originalValue set in initComponent().

sudden_def
6 May 2009, 11:24 PM
And what if the field has no initial value? The first setValue() call will initialize originalValue with the passed value and isDirty will return false instead of true.

mystix
6 May 2009, 11:36 PM
And what if the field has no initial value? The first setValue() call will initialize originalValue with the passed value and isDirty will return false instead of true.

unless i'm mistaken, i should think that's prevented by @condor's override above.

mystix
7 May 2009, 1:30 AM
and for reference, here's the original bug report for 2.2:
http://extjs.com/forum/showthread.php?p=244525#post244525