vaadin / flow-components

Java counterpart of Vaadin Web Components
100 stars 66 forks source link

IntegerField / AbstractNumberField: Validation for Min/Max has no message / prevents custom validation #6055

Open hoshie82 opened 7 months ago

hoshie82 commented 7 months ago

Description

If you set a range for a number field and enter an invalid value, there is no error message shown, because the validation result returns an empty error message.. It is not possible to do a custom validation because that validation is not triggered, after the default validator has failed.

Expected outcome

Either the default validator should be triggered after all custom validators have been fired, or the validation result should contain all errors... Or: custom error messages for Min/Max should be possible for the number fields.

Minimal reproducible example

        VerticalLayout layout = new VerticalLayout();
        IntegerField field = new IntegerField();
        field.setMin(50); // for this test, other values than custom validator
        field.setMax(250);
        Button button = new Button("validate");
        layout.add(field, button);
        Binder<TestObject> binder = new Binder<>();
        binder.forField(field)
                .withValidator((v, ctx) -> {
                    if (v == null) {
                        return ValidationResult.ok();
                    }
                    if (v < 100 || v > 200) {
                        return ValidationResult.error("not valid");
                    }
                    return ValidationResult.ok();
                })
                .bind(TestObject::getValue, TestObject::setValue);

        button.addClickListener(e -> {
            BinderValidationStatus<TestObject> state = binder.validate();
            if (state.hasErrors()) {
                String msg = state.getValidationErrors().stream()
                        .map(ValidationResult::getErrorMessage).collect(Collectors.joining("\n"));
                Notification.show(msg);
            }
        });

Steps to reproduce

if you enter the value 40, nothing is shown, because the default validator of the integer field is triggered. The custom validator does nothing. If you enter the value 50, the "not valid" message is shown, because the custom validator is triggered.

Environment

Vaadin version(s): 24.3.5 OS: win10

Browsers

Issue is not browser related

knoobie commented 7 months ago

See https://github.com/vaadin/flow-components/issues/4618

yuriy-fix commented 7 months ago

In the latest version you are also able to skip default validator: https://github.com/vaadin/flow/issues/17178.

hoshie82 commented 7 months ago

@yuriy-fix problem is, that I don't want to skip all default validators at the binder, because "some" of the validators make sense... Skipping this validator would be better for my use case, because I only use the min/max attributes at client side.

@knoobie adding additional messages would be great. But in my oppinion the custom validation should be also preferred against the default-validator, if only one error message is shown.

Same problem with "asRequired()" at the binder, but at least you can add a custom message there.

knoobie commented 7 months ago

The binder works by "stopping" at the first error; therefore the default validation of the field (with no error message) is triggered before your validation runs, so this kind of precedence is currently not there.