vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
621 stars 167 forks source link

Method to get bean level BinderValidationStatus when using read/writeBean #13393

Closed bsutton closed 2 years ago

bsutton commented 2 years ago

Describe your motivation

I'm using vaadin 22 with a form that uses read/writeBean.

I'm trying to add cross field validation to the binder:

binder.withValidator(new Validator<DiscountCode>()
        {
            @Override
            public ValidationResult apply(DiscountCode value, ValueContext context)
            {
                                 if (bad) return false;
                return ValidationResult.ok();
            }
        });

If I call binder.writeBeanIfValid it returns false (as expected) when bad is true.

The problem is that I need to get the BinderValidationStatus list when writeBeanIfValid returns false.

The only way I can see to get the list of status' is via a call to binder.validate. The problem is that binder.validate throws the following exception:

java.lang.IllegalStateException: Cannot validate binder: bean level validators have been configured but no bean is currently set
    at com.vaadin.flow.data.binder.Binder.validate(Binder.java:2479) ~[flow-data-9.0.8.jar:9.0.8]
    at com.vaadin.flow.data.binder.Binder.validate(Binder.java:2463) ~[flow-data-9.0.8.jar:9.0.8]
    at dev.onepub.ui.crud.editor.EditorFormLayout.saveEdits(EditorFormLayout.java:75) ~[classes/:?]
    at dev.onepub.ui.crud.editor.EditorLayout.saveEdits(EditorLayout.java:132) ~[classes/:?]

I can't use setBean as I don't want the form to automatically write to the bean.

Hopefully I've missed something and this feature already exists but I've been through the binder source code and can't see a path.

Describe the solution you'd like

Add a variation of validate that allows a bean to be passed.

binder.validate(bean);

Describe alternatives you've considered

Overloading the binder.getBean and returning a bean during the validation call when it calls getBean

Additional context

No response

vaadin-bot commented 2 years ago

Thanks for using Vaadin! We appreciate your help and we’ll take care of this as soon as possible.

mcollovati commented 2 years ago

Did you tried with Binder.setValidationStatusHandler(...) ? It is invoked at the end of writeBeanIfValid() and it gets as input a BinderValidationStatus<BEAN>. Can this help with your use case?

mshabarov commented 2 years ago

This ticket is being closed due to inactivity. Please provide your feedback in a comment, so we can proceed with it, or create a new ticket if this issue is still actual for you.