vaadin-component-factory / masked-text-field

Apache License 2.0
0 stars 1 forks source link

Component is not working with Binder #1

Open mlopezFC opened 1 year ago

mlopezFC commented 1 year ago

Take into account the following code:

@Route
public class MainView extends VerticalLayout {

    Binder<Person> binder = new Binder<>();
    Button saveButton = new Button("Save");

    MaskedTextField maskedTextField;

    public MainView() {

        Person p = new Person();
        binder.setBean(p);
        maskedTextField =
                new MaskedTextfield(new MaskedTextFieldOption("mask", "0000"));

        binder.forField(maskedTextField)
            .asRequired("Required field")
            .withValidator(string->!string.equals("1111"),"error 1")
            .withValidator(string->!string.equals("2222"),"error 2")
            .bind(Person::getTaxId, Person::setTaxId);

        saveButton.addClickListener(ce -> {
            if (binder.validate().isOk())
            {
                Notification.show("Field saved");
            }
        });
        add(maskedTextField,saveButton);
    }
}

If I start the application and write "1111" to the field, it will show an error because of the first validator. If I blur away and then enter "2222" it should display the second error and it is not doing that. After that no errors are shown until I clear the field and start again.

This behavior can be seen in the following animated gif:

MaskedTextField

Versions:

mlopezFC commented 1 year ago

It seems that the problem is related to the required indicator. If instead of using .asRequired() we use the following code, then it works:

@Route
public class MainView extends VerticalLayout {

    Binder<Person> binder = new Binder<>();
    Button saveButton = new Button("Save");

    MaskedTextField maskedTextField;

    public MainView() {

        Person p = new Person();
        binder.setBean(p);
        maskedTextField =
                new MaskedTextField(new MaskedTextFieldOption("mask", "0000"));

        binder.forField(maskedTextField)
        .withValidator(Validator.from(
                value -> {
                  return !Objects.equals(value, maskedTextField.getEmptyValue());
                },
                ctx -> "Field is required"))
            .withValidator(string->!string.equals("1111"),"error 1")
            .withValidator(string->!string.equals("2222"),"error 2")
            .bind(Person::getTaxId, Person::setTaxId);

        saveButton.addClickListener(ce -> {
            if (binder.validate().isOk())
            {
                Notification.show("Field saved");
            }
        });
        add(maskedTextField,saveButton);
    }
}

BTW: this is not a workaround, because it cannot be used with required indicator