Could you explain in which order you are doing things in the UI, what the results are, and what you expect?
You see, you do not have a ValueChangeListener in the example, and that is when the value is changed - TextChange happens while the user is typing, while ValueChange happens when the value is actually applied.
In your example, getVAlue() should be ‘trailing behind’:
enter “asd” → value=“”,text=“asd”
tab out → value=“asd”
focus again, type “foo” → value=“asd”, text=“asdfoo”
tab out → value=“asdfoo”
Also note that TextChange is only an event occurring when you type into the field, so getText() is only available during the event, while getValue() gets the actual value of the TextField (value is a propety that is always available).
The value change happens when you tab out, or otherwise unfocus the field, because it’s ‘immediate’ in your example. If it’s not, value will be updated when the next server roundtrip occurs, e.g when you press a button.
Thanks for your detailed explanation.our project has a validation when text of the TextField changed, but we use TextChangeEvent to check, it is wrong. we should use
I am trying to implement a live validation framework (similar as chan guang). The TextChange event is the only one I can use, since that event gives me updates during typing. Unfortunately the actual value is still the old one as you describe, which results in a isValid() call which uses the old value and hence is not usable.
I’ve tried setting the value of the component using setValue(event.getText()) but that introduces unexpected behavior (text parts missing, cursor position changes in internet exporer, …). The ValueChangeListener would be an excellent event for me to use - if it would be triggered during text change and not only after unfocus.
Live validation as described on http://livevalidation.com/examples is what I’d like to achieve - but I couldn’t find a sample implementation using Vaadin. Do you have any pointer on how to solve this?
(Sidenote: this is IMO enough of a different issue to warrant a new thread - please create new threads for issues like this, so that other people can find them later… )
This is not pretty, but you probably get the idea:
final TextField text = new TextField();
final Label message = new Label();
addComponent(text);
addComponent(message);
text.addValidator(new StringLengthValidator("Length FAIL!", 3, 10, true));
text.addValidator(new RegexpValidator("[^xX]
*", "No X allowed!"));
text.addListener(new TextChangeListener() {
@Override
public void textChange(TextChangeEvent event) {
String err = "";
// run validators 'manually'
for (Validator v : text.getValidators()) {
try {
v.validate(event.getText());
} catch (InvalidValueException e) {
err += e.getMessage() + " ";
}
}
if (err.length() > 0) {
message.setValue(err);
} else {
message.setValue(null);
}
}
});
Something like that?
Summary:
Run the validators separately, not trough TextField.validate() which will use the ‘old’ value.
Don’t touch the TextField, or you’ll probably end up ‘overwriting’ the text being typed in the client.