How to show save buttons only on valid changes? Vaadin 23

Hi all,

I use the binder and want to enable a save buttons only when the user provides valid input.
Valid input means = the user changed something and that new value is valid.

I had two believes which I now realise are wrong.

  1. Validation happens already on input, not only on write(bean)

  2. binder.addStatusChangeListener(…) is also called when the user enters data. As can be found in the documentation that happens because of the validate() method:
    https://vaadin.com/api/platform/23.2.0/com/vaadin/flow/data/binder/StatusChangeEvent.html

The result is that I get way more StatusChangeEvent than I thought while getting also
ValueChangeEvent together with StatusChangeEvent.

Is there a way to just get the events I expect?

I found this old post:
https://vaadin.com/forum/thread/14981126/vaadin-8-binder-addstatuschangelistener
and to me it looks like there is still no nice solution to this problem.

Basically I would like to do something like: binder.setValidationOnlyOnWrite()

Any ideas?

Thanks!

And in which use case is binder.addStatusChangeListener helpful?

What seems to work as I want is this:

    private void enableOnValidChange(HasEnabled s) {
        binder.addValueChangeListener(e -> {
            if (binder.isValid()) {
                s.setEnabled(true);
            }else {
                s.setEnabled(false);
            }
        });
    }

This is how I would implement it.
In my opinion, disabling the button is not user friendly since you don’t know why. Especially for a big form.

@faithful-emu And in which use case is binder.addStatusChangeListener helpful?
The save button gets enabled on the view as soon as enough data has been given. I find that makes more sense then just to let the use press a button to figure out some fields need values/show validation errors.

I use a very strong color for my save buttons, maybe that got me thinking I should disable them by default.

I would argue against disabling as well. The added complexity isn’t worth it - especially it doesn’t really help the user. With a disabled button the user has to search all fields where the required indicator tells him the field is missing (little dot, easy to miss) until the form is fully filled / valid

With an always enabled button, the user can just press it and gets instantly big red fields where he missed the input and if you wanna be awesome, you could even scroll to the fields or focus them

Yeah, I see the point. Lets say I will not disable the button by default.

In which scenarios are then binder.addStatusChangeListener and binder.addValueChangeListener useful?

I would use status change listener if I would need an external component to display all errors from every field (like a notification)

Not sure about the practical use case of the value change listener tho, but if I remember correctly it gets always called no matter what fields’ value changed allowing for a similar “all in one place logic” like the status change from above

It seemed to me the status change listener is always called, because validation raises the event.

The value changed listener only gets called when a value changed by the user.

Thanks for your feedback Christophe and knoobie. Maybe I made things to complicated for me, which is sometimes the goal to test my understanding.

I had the same feeling about the status listener, I don’t know when it’s useful .

I like to disable the button if no change in the form. Then always enable it.