-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add methods to modify an existing binding #5030
Comments
Hi @heruan |
@berndklb I have to test it yet, but it seems like it! |
Any update on this? |
@berndklb Can't find your branch anymore, is it still available? |
I cleaned up a while ago, but I repushed the branch. |
Thank you @berndklb for pushing that again. In the meanwhile, I've crafted a custom public class CustomBinder<T> extends Binder<T> {
public interface CustomBinding<T, V> extends Binding<T, V> {
default void setRequired(boolean required) {
if (required) {
this.setRequired(context -> "");
} else {
this.setRequired(Validator.alwaysPass());
}
this.getField().setRequiredIndicatorVisible(required);
this.validate(false);
}
void setRequired(ErrorMessageProvider errorMessageProvider);
void setRequired(Validator<V> validator);
}
public interface CustomBindingBuilder<T, V> extends BindingBuilder<T, V> {
@Override
default CustomBindingBuilder<T, V> asRequired() {
return this.asRequired(context -> "");
}
@Override
default CustomBindingBuilder<T, V> asRequired(String errorMessage) {
return this.asRequired(context -> errorMessage);
}
@Override
CustomBindingBuilder<T, V> asRequired(ErrorMessageProvider errorMessageProvider);
@Override
CustomBindingBuilder<T, V> asRequired(Validator<V> customRequiredValidator);
@Override
CustomBinding<T, V> bind(ValueProvider<T, V> getter, Setter<T, V> setter);
}
protected static class CustomValidatorImpl<T> implements Validator<T> {
private Validator<T> upstream;
public CustomValidatorImpl(Validator<T> upstream) {
this.upstream = upstream;
}
@Override
public ValidationResult apply(T value, ValueContext context) {
return this.upstream.apply(value, context);
}
}
protected static class CustomBindingBuilderImpl<T, U, V> extends BindingBuilderImpl<T, U, V>
implements CustomBindingBuilder<T, V> {
private final HasValue<?, U> field;
private final Converter<U, V> converterValidatorChain;
private CustomValidatorImpl<V> requiredValidator;
protected CustomBindingBuilderImpl(Binder<T> binder, HasValue<?, U> field,
Converter<U, V> converterValidatorChain,
BindingValidationStatusHandler statusHandler) {
super(binder, field, converterValidatorChain, statusHandler);
this.field = field;
this.converterValidatorChain = converterValidatorChain;
}
@Override
public CustomBindingBuilder<T, V> withValidator(Validator<? super V> validator) {
super.withValidator(validator);
return this;
}
@Override
public CustomBindingBuilder<T, V> asRequired(ErrorMessageProvider errorMessageProvider) {
return this.asRequired((v, c) -> Validator.<V>from(value -> {
var emptyValue = this.field.getEmptyValue();
var convertedValue = this.converterValidatorChain.convertToPresentation(value, c);
return !Objects.equals(convertedValue, emptyValue);
}, errorMessageProvider).apply(v, c));
}
@Override
public CustomBindingBuilder<T, V> asRequired(Validator<V> customRequiredValidator) {
this.requiredValidator = new CustomValidatorImpl<>(customRequiredValidator);
this.checkUnbound();
this.field.setRequiredIndicatorVisible(true);
return this.withValidator(this.requiredValidator);
}
@Override
public CustomBinding<T, V> bind(ValueProvider<T, V> getter, Setter<T, V> setter) {
var upstream = super.bind(getter, setter);
return new CustomBindingImpl<>(upstream, this);
}
}
protected static class CustomBindingImpl<T, U, V> implements CustomBinding<T, V> {
private final Binding<T, V> upstream;
private final HasValue<?, U> field;
private final Converter<U, V> converterValidatorChain;
private final CustomValidatorImpl<V> requiredValidator;
public CustomBindingImpl(Binding<T, V> upstream,
CustomBindingBuilderImpl<T, U, V> builder) {
this.upstream = upstream;
this.field = builder.field;
this.converterValidatorChain = builder.converterValidatorChain;
this.requiredValidator = builder.requiredValidator;
}
@Override
public void setRequired(ErrorMessageProvider errorMessageProvider) {
this.setRequired((v, c) -> Validator.<V>from(value -> {
var emptyValue = this.field.getEmptyValue();
var convertedValue = this.converterValidatorChain.convertToPresentation(value, c);
return !Objects.equals(convertedValue, emptyValue);
}, errorMessageProvider).apply(v, c));
}
@Override
public void setRequired(Validator<V> validator) {
this.requiredValidator.upstream = validator;
}
@Override
public HasValue<?, ?> getField() {
return this.upstream.getField();
}
@Override
public BindingValidationStatus<V> validate(boolean fireEvent) {
return this.upstream.validate(fireEvent);
}
@Override
public BindingValidationStatusHandler getValidationStatusHandler() {
return this.upstream.getValidationStatusHandler();
}
@Override
public void unbind() {
this.upstream.unbind();
}
@Override
public void read(T bean) {
this.upstream.read(bean);
}
@Override
public void setReadOnly(boolean readOnly) {
this.upstream.setReadOnly(readOnly);
}
@Override
public boolean isReadOnly() {
return this.upstream.isReadOnly();
}
@Override
public ValueProvider<T, V> getGetter() {
return this.upstream.getGetter();
}
@Override
public Setter<T, V> getSetter() {
return this.upstream.getSetter();
}
}
@Override
public <U> CustomBindingBuilder<T, U> forField(HasValue<?, U> field) {
return (CustomBindingBuilder<T, U>) super.forField(field);
}
@Override
protected <U, V> BindingBuilder<T, V> doCreateBinding(HasValue<?, U> field,
Converter<U, V> converter, BindingValidationStatusHandler handler) {
return new CustomBindingBuilderImpl<>(this, field, converter, handler);
}
} But I still think the feature should be on core, so I hope to get rid of this soon 🙂 |
Acceptance Criteria
This feature is up for grabs for contributing, please read the contribution guidelines https://github.com/vaadin/flow/blob/master/CONTRIBUTING.md and ask any questions in here or eg. https://gitter.im/vaadin/flow if necessary. |
It is a very common use case in complex form that whether a field is required or not, it depends on input on other fields. Hypothetical use case sample could be that we have form for a Product and price of the product is needed except in case the Product's type is Sample. So in that kind of scenarios it would be needed to turn off asRequired() validation easily. The purpose of this enhancement and new binding.setAsRequiredEnabled(..) API is to help implementation of this kind of use cases more easily. There is more generic ticket about conditional validation, and this PR is partially addressing it #10709 Cherry pick from vaadin/framework#11834 Requested in #5030
It is a very common use case in complex form that whether a field is required or not, it depends on input on other fields. Hypothetical use case sample could be that we have form for a Product and price of the product is needed except in case the Product's type is Sample. So in that kind of scenarios it would be needed to turn off asRequired() validation easily. The purpose of this enhancement and new binding.setAsRequiredEnabled(..) API is to help implementation of this kind of use cases more easily. There is more generic ticket about conditional validation, and this PR is partially addressing it #10709 Cherry pick from vaadin/framework#11834 Requested in #5030
- Enable / disable all validators on Binder level - Enable / disable validators on Binding level - add writeBeanAsDraft(bean,boolean) for writing draft bean with validators disabled Fixes: #5030
- Enable / disable all validators on Binder level - Enable / disable validators on Binding level - add writeBeanAsDraft(bean,boolean) for writing draft bean with validators disabled Fixes #5030
- Enable / disable all validators on Binder level - Enable / disable validators on Binding level - add writeBeanAsDraft(bean,boolean) for writing draft bean with validators disabled Fixes #5030
- Enable / disable all validators on Binder level - Enable / disable validators on Binding level - add writeBeanAsDraft(bean,boolean) for writing draft bean with validators disabled Fixes #5030
Given an existing binding, it's currently not possible to modify its properties; for example, given
I might need to add additional validation, like:
binding.setRequired(true)
binding.addValidator(validator)
depending on user actions or status of other fields.
The text was updated successfully, but these errors were encountered: