flow
flow copied to clipboard
Provide access to all validation errors in Binder
I have a form that is split up into separate tabs that all share the same Binder. I'd like to show an indicator in each tab if it contains at least one field for which there is a validation error.
I can use addStatusChangeListener or setValidationStatusHandler to get an event whenever some validation status might have changed, but the problem is that I cannot directly get the current list of all validation errors. BinderValidationStatus provides getFieldValidationErrors() but that method does only consider the affected field when the validation status is updated because of a value change from a specific field. The same method returns all validation errors if the validation status is updated because of a global action such as validate().
The only way of consistently finding all current validation errors is by explicitly calling validate(), but this has two problems:
validate()triggers the validation status handler, which leads to infinite recursion when used from inside the validation status handlervalidate()resets the UI mode that prevents showing initial validation errors until the user has touched the field or tried to submit the form
The workaround that I ended up using is to keep my own collection of fields with validation errors and then use BinderValidationStatus::getFieldValidationStatuses to find all fields for which the status might have changed and use that to find out fields to add or remove field from my collection.
Some ideas for how to better support this kind of use case:
- Provide a public method that returns current validation errors without triggering any side effects
- Update the methods in
BinderValidationStatus(or introduce overloads for this purpose) to consistently cover all bindings instead of only bindings that might have changed.
I'm trying to deal with this exact same problem. Using tabs provides a poor user experience when a validation error occurs as they can't see error if they are on a different tab. I need to be able to get the field associated with the error, so that I can then get the owner (the tab that is holding the field) so that I can show an error notification on that tab.
I currently have the same issue. I want to know if the Binder status is valid without triggering all the validations. First because there are many and second because they may access the database.
I think there is a workaround in Vaadin 24.4. It introduces a new method Binder#getChangedBindings and via Binding you can get the fields status
((HasValidationProperties) binding.getField()).isInvalid();
So that could be the key here. I.e. collect those into stream and short circuit it with any match.
I tried that but it always returns an empty set.
I tried that but it always returns an empty set.
That means that there is no changes ... Should that imply there is no new validation errors unless the bean is backfilled with values from business logic.
If you use readBean, getChangedBindings should provide all changed bindings (valid or invalid) which have not yet been committed using writeBean.
When using setBean it becomes more cumbersome since valid changes are committed to the bean immediately, so you can never get them. However if there are bindings that have changed and are in invalid state after the change, they should be returned by getChangedBindings. If they are not, then something is broken in Binder.
Also, a fundamental problem with
I want to know if the Binder status is valid without triggering all the validations.
is that then we must assume that the initial data set via readBean or setBean is valid since no validation is initially done, and if something external triggers field validation, the validation errors are initially hidden.