Skip to content
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

Calling binder.validate() does not work correctly when run afterNavigation #21017

Open
TatuLund opened this issue Feb 20, 2025 · 0 comments
Open

Comments

@TatuLund
Copy link
Contributor

TatuLund commented Feb 20, 2025

Description of the bug

When I populate my form in afterNavigation, which should be the most common scenario, i.e. usually loading data from backend is premature in the constructor or beforeEnter. If in my application it is possible that backend has invalid data, which needs to be corrected, I want to call binder.validate() after readBean. This kind of backfilling process is rather common.

Now for some reason DatePicker and IntegerField are still shown valid, although the date is in the past.

There is a workaround to delay validate call to the next client roundtrip

    @Override
    public void afterNavigation(AfterNavigationEvent event) {
        var pojo = new Pojo();
        pojo.setDate(LocalDate.of(1971, 12, 10));

        binder.readBean(pojo);
        getElement().executeJs("return 0;").then(res -> {
            binder.validate();
        });
    }

Expected behavior

The fields are shown invalid.

Minimal reproducible example

Use the view below to replicate the issue:

@Route(value = "datepicker", layout = MainLayout.class)
public class DatePickerView extends VerticalLayout
        implements AfterNavigationObserver {

    private Binder<Pojo> binder;

    public DatePickerView() {
        setMargin(true);
        setSpacing(true);
        setSizeFull();

        var datePicker = new DatePicker();
        var integerField = new IntegerField();

        binder = new Binder<>();

        binder.forField(datePicker)
                .withValidator(value -> value.isAfter(LocalDate.now()),
                        "No future")
                .bind(Pojo::getDate, Pojo::setDate);
        binder.forField(integerField)
                .withValidator(value -> value >= 0, "No positive")
                .bind(Pojo::getNumber, Pojo::setNumber);

        add(datePicker, integerField);
    }

    @Override
    public void afterNavigation(AfterNavigationEvent event) {
        var pojo = new Pojo();
        pojo.setDate(LocalDate.of(1971, 12, 10));
        pojo.setNumber(-10);

        binder.readBean(pojo);
        binder.validate();
    }

    public class Pojo {
        private LocalDate date;
        private Integer number;

        public LocalDate getDate() {
            return date;
        }

        public void setDate(LocalDate date) {
            this.date = date;
        }

        public Integer getNumber() {
            return number;
        }

        public void setNumber(Integer number) {
            this.number = number;
        }
    }
}

Versions

  • Vaadin / Flow version: 24.6.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant