Skip to content

Instantly share code, notes, and snippets.

@johannest
Created March 20, 2024 08:55
Show Gist options
  • Save johannest/b57b49f4e1ac732079d270db50f988dd to your computer and use it in GitHub Desktop.
Save johannest/b57b49f4e1ac732079d270db50f988dd to your computer and use it in GitHub Desktop.
package org.vaadin.example;
import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.BinderValidationStatus;
import com.vaadin.flow.data.binder.Validator;
import java.util.ArrayList;
import java.util.List;
/**
* Wrapper class for making it possible to bind validation to single V23/24 field component
*
* @param <T> Type of the field's value
* @param <FIELD> Field's type
*/
public class BinderWrapper<T, FIELD extends HasValue<?, T>> {
private final Binder<WrapperBean<T>> binder;
private Binder.Binding<WrapperBean<T>, T> binding;
private final FIELD field;
private boolean required;
private boolean validationVisible = true;
private List<Validator<? super T>> validators = new ArrayList<>();
public static class WrapperBean<V> {
private V value;
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
public BinderWrapper(FIELD field) {
this.field = field;
this.binder = new Binder<>();
this.binder.forField(field)
.bind(WrapperBean<T>::getValue, WrapperBean<T>::setValue);
}
public void addValidator(Validator<? super T> validator) {
validators.add(validator);
this.binder.forField(field)
.withValidator(validator)
.bind(WrapperBean<T>::getValue, WrapperBean<T>::setValue);
}
public void removeValidator(Validator<T> validator) {
validators.remove(validator);
reBind();
}
public boolean validate() {
BinderValidationStatus<WrapperBean<T>> status = this.binder.validate();
return status.isOk();
}
public void setRequired(boolean required) {
this.required = required;
reBind();
}
public void setValidationVisible(boolean validationVisible) {
this.validationVisible = validationVisible;
reBind();
};
public boolean isRequired() {
return required;
}
public boolean isValidationVisible() {
return validationVisible;
}
public List<Validator<? super T>> getValidators() {
return validators;
}
private void reBind() {
if (binding != null) {
binder.removeBinding(binding);
}
Binder.BindingBuilder<WrapperBean<T>, T> bindingBuilder = this.binder.forField(field);
if (required) {
bindingBuilder = bindingBuilder.asRequired("This field is required");
}
if (!validators.isEmpty() && validationVisible) {
for (Validator<? super T> validator : validators) {
bindingBuilder.withValidator(validator);
}
}
binding = bindingBuilder.bind(WrapperBean<T>::getValue, WrapperBean<T>::setValue);
if (!required) {
// Note: Removing the required indicator might not directly map to the asRequired functionality.
this.field.setRequiredIndicatorVisible(false);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment