Search code examples
javavaadinvaadin7

How to create a real time validator on a text field in Vaadin?


I am currently using Vaadin 7.3+ and want to validate in a text field as the user types in real time.

This is what I tried so far:

textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
textField.setNullRepresentation("");

textField.addTextChangeListener(new FieldEvents.TextChangeListener() {
    @Override
    public void textChange(FieldEvents.TextChangeEvent event) {
        for (Validator v : textField.getValidators()) {
            try {
                v.validate(event.getText());
            } catch (InvalidValueException e) {
                log.warn("validation error: " + e.getMessage() + " and value was: {}", event.getText());
            }
        }
    }
});

The problem is that although all the validators are being executed and validation is being done the red error indicator is not rendered until the focus leaves the field, i.e. the user hits enter or clicks somewhere else. I tried adding textField.markAsDirty but this did not work. Does anyone know of a solution to this problem? Or of a better solution in general for creating a real time validator on a text field?

Thanks in advance for your time and input :-)


Solution

  • This straight forward workaround solution seems to work fine although it is quite inelegant.

    textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
    textField.setNullRepresentation("");
    
    textField.addTextChangeListener(new FieldEvents.TextChangeListener() {
        @Override
        public void textChange(FieldEvents.TextChangeEvent event) {
            try {
                textField.setValue(event.getText());
    
                // workaround cursor position problem
                textField.setCursorPosition(event.getCursorPosition());
    
                textField.validate();
                } catch (InvalidValueException e) {
                    log.warn("validation error: " + e.getMessage() + " and value was: {}", delegate.getValue());
                }
        }
    });