I was trying to use javax validation with binder.writeBean and then add the validation errors to the respective fields. It took me a while to get to this and I thought it might be useful for someone else. Maybe there’s a better easier way to do the same thing?
Normally the validation errors should be automatically linked to the field. The only problem should be for Bean validation (crossfield validation because it’s not linked to a field).
And if your bean is not valid when you enter in your screen (for example when you create a new bean), then you can call studentBinder.validate() before writeBean or you can wait for Vaadin 8.2.
Person person = new Person("John", 26);
BeanItem<Person> item = new BeanItem<Person>(person);
TextField firstName = new TextField("First name",
item.getItemProperty("name"));
firstName.setImmediate(true);
setContent(firstName);
BeanItem has been removed since Vaadin 8.
setImmediate is true by default since Vaadin 8.
And after there is this code:
firstName.addValidator(new BeanValidator(Person.class, "name"));
addValidator has been removed since Vaadin 8 from TextField.
So I prefer the other documentation for Vaadin 8 :).
This code is ok for Vaadin 8:
TextField firstName = new TextField("First name");
Person person = new Person("John", 26);
BeanValidationBinder<Person> binder = new BeanValidationBinder<>(Person.class);
binder.forField(firstName).bind("name");
binder.setBean(person);
setContent(firstName);
I clone it and don’t see any JSR validation done by Vaadin, when I try it and put invalid data I’ve got a stacktrace:
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [org.vaadin.stepbystep.person.backend.Person]
during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage=‘First Name must be longer than 3 and less than 40 characters’, propertyPath=firstName, rootBeanClass=class org.vaadin.stepbystep.person.backend.Person, messageTemplate=‘First Name must be longer than 3 and less than 40 characters’}
]
Thank you for reporting this as well! I have
fixed the code to report the bean validation errors on the UI, and
one more tweak to prevent saving at all till all errors are gone.
Thanks for the pull request.
The problem in your example with the tweak setValidationStatusHandler is: the default behaviour is removed (display errors on each field).
So your save button is disabled but you don’t know why (email invalid or less than 3 chars in your name).
I don’t how to add a new validationStatushandler and keep the default one. (Perhaps if you extend binder)
Perhaps you can use this (don’t know if it’s ok or not):
binder.addValueChangeListener(e → save.setEnabled(!binder.hasChanges())); // no uncommited changes = bean is valid
instead of:
binder.setValidationStatusHandler(status → { save.setEnabled(status.isOk()); });
Thanks again,
fixed by monitoring the status change instead of overriding the validation handler.
Another way of doing it is to keep a reference of the old handler and apply the new status on it:
oldHandler = binder.getValidationStatusHandler();
binder.setValidationStatusHandler(status -> {
save.setEnabled(status.isOk());
oldHandler.statusChange(status);
});
Having a possiblity to add handler would be better, that’s why I made a
feature request on Github.