I’m starting my first project in Vaadin 8 (after ~10 successful projects in Vaadin 7) and I have noticed that fields no longer have the setRequired() method.
In Vaadin 7, if I wanted to set a field to be required/not-required, all I had to do was call setRequired() and that would implicitly add “required” validation to the field.
The closest thing in Vaadin 8 that I have found to the setRequired() method is asRequired():
binder.forField(nameField).asRequired("Every employee must have a name").bind("name");
This works as expected, but what I want to know is: If I call asRequired() and bind a field, how do I later say that the field is no longer required?
Is there a way to remove the “required” Validator (or any other Validator) after I bind a field?
Often times in the applications I develop, it is necessary to set a certain field to be required/not-required depending on the value that the user enters in some other field in the form.
Ok, I solved (but I’m not happy about the way), using method setRequiredIndicatorVisible() of widget to dinamically display required mark. Then I set a validator like the following, on each need field:
public ValidationResult validateRequired(String value, ValueContext context) {
Component c = context.getComponent().orElse(null);
if (c != null && c instanceof HasValue && ((HasValue<?>) c).isRequiredIndicatorVisible()
&& (StringUtils.isBlank(value)))
return ValidationResult.error("Value required for " + c.getCaption()));
return ValidationResult.ok();
}
This is really hard to translate into a Vaadin-8-app.
Also because the setter for the error messages are not available (in Vaadin-7 there was a AbstractValidator.setErrorMessage method, in Vaadin-8 not any more).
Do you know how the change the validation-message of a binder afterwards?
There is a way to make a dynamic required error message using
binder.forField(textField)
.asRequired(context -> /* insert your method returning a String here */)...;
the
context variable is an instance of
ValueContext , which contains information like the currently used locale, the component and its value.
We had a discussion at some point about changing the required validator to check for the
isRequiredIndicatorVisible() and skip the validation if it was
false , but this would have some unexpected side-effects for some users.
The
asRequired is implemented using the normal
withValidator method with the following
Predicate
value -> !Objects.equals(value, field.getEmptyValue())
To make your own
RequiredValidator that checks if the required indicator is visible, only requires one if clause wrapping the predicate above.