View Full Version : Listening for Field changes after clearing a validation error
cravemusic
27 Oct 2008, 10:05 AM
The Field class fires a Change event on the blur of a field anytime the contents in the field change. However, if the field has validation on it (like a DateField or a NumberField), the Change event does not fire under the following circumstances (using a Date as an example):
1. Have valid date in the field.
2. Make the date field invalid by entering something like "aaa" into it
3. Fix the validation error by blanking the contents of the field.
I filed a bug (http://extjs.com/forum/showthread.php?t=50332) on this, but Darrell believes this is the proper behavior (see the bug thread (http://extjs.com/forum/showthread.php?t=50332) for why). So, I'm looking for a workaround -- I somehow need to get notified about the field Change, because from the user's perspective, they changed a date to blank -- so all of the stuff that happens when a field's value changes should happen. The fact that there was an invalid state in the middle shouldn't make a difference.
I tried hooking on to the Valid and Invalid events as well, but the evt.oldValue and evt.value payloads I need are always null (the Change event has non-null values for those payloads).
Can any one provide some ideas on how I might get around this?
gslender
27 Oct 2008, 1:07 PM
hook into onBlur and then call validate on the field? or if you have to, clear the invalid status. check out my password field in the Gxt: User Extensions and Plugins
I do a few things with fields etc to get notifications etc...
cravemusic
28 Oct 2008, 12:42 PM
Yea, I would up extending and overriding the onFocus and onBlur methods from the root Field.java class to meet my needs. The only problem with that is that I have the same problem on several different field types, so I have to extend each separately with the exact same code, because I can't extend the root Field class without breaking the inheritance chain for org. fields I extended.
darrellmeyer
28 Oct 2008, 6:01 PM
However, if the field has validation on it (like a DateField or a NumberField), the Change event does not fire under the following circumstances (using a Date as an example):
1. Have valid date in the field.
2. Make the date field invalid by entering something like "aaa" into it
3. Fix the validation error by blanking the contents of the field.Anytime a field receives focus, and then blurs with a different value, a change event should fire.
1. Field receives focus with previous valid date set.
2. Enters invalid date
3. Blurs - change event will fire, value will be null
4. Focus again
5. Change to valid value
6. Blurs - change event will fire
1. Field receives focus with previous valid date set.
2. Enters invalid date
3. Blurs - change event will fire, value will be null
4. Focus again
5. Change to empty
6. Blurs - no change event as value is still null from step 3
In both scenarios you will always be notified when a value changes. Thoughts?
cravemusic
29 Oct 2008, 9:49 AM
The problem is that, conceptually, we're dealing with two different meanings of null:
* User invalidates a field -- the Java type for the field data is Date, so you can't set the value of a Date object to something like "aaaa", so instead, represent it as a null value
* User indicates that a field should be without value -- represent the empty value as null
When in a situation as initially described in my first post on this thread, both of these meanings of null are used. So, while comparing the values in the field, null == null, so therefore no change event, the meaning of null in each case is very different, and as a result, different code paths may be keyed off of these different meanings.
Here's a solution I propose:
Inside of the Field class, maintain a variable of type D (called valueBeforeError here) that keeps track of the field value across validations, and only change this variable when a field successfully passes validation. Implementation would look something like this:
protected void onBlur(ComponentEvent be) {
if ( !GXT.isOpera && focusStyle != null ) {
getFocusEl().removeStyleName(focusStyle);
}
hasFocus = false;
if ( super.getValidateOnBlur() ) {
validate();
}
if ( isValid() ) {
if ( (focusValue == null && getValue() != null) ||
(focusValue != null && !focusValue.equals(getValue())) {
fireChangeEvent(focusValue, getValue());
}
else if(valueBeforeError != null && getValue() == null) {
fireChangeEvent(valueBeforeError, getValue());
valueBeforeError = null;
}
}
fireEvent(Events.Blur, new FieldEvent(this));
}
protected void onFocus(ComponentEvent ce) {
if ( isValid() ) {
// only set this when valid:
// user may have entered something invalid but then went to another field
valueBeforeError = getValue();
}
super.onFocus(ce);
}
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.