Anna K
Anna K

Reputation: 1774

Form validation with Binder

How to finish validation with sending all form data in Vaadin 8? Unfortunetly I dont understand binder concept :( I wrote a field validation but what now? It works. My user see when I demand that he fill out a field but is there any easy way to validate my all form? How can I "tell" to my save button that my form is valid?

enter image description here

In my editor Im defining a validator

@SpringComponent
@PrototypeScope
public class VaadinStringEditor extends TextField implements HasValueComponent<String> {

    private Binder<String> binder;
    BinderValidationStatus<String> status;
    @PostConstruct
    public void init() {
        setWidth("100%");
        binder = new Binder<>();
    }

    @Override
    public void initDefaults() {
        setValue("");
        status = binder.validate();

    }

    @Override
    public void setConfiguration(EditorConfiguration editorConfiguration) {
        Validator<String> validator = ((TextFieldConfiguration) editorConfiguration).getValidator();
        if (validator != null) {
            binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(),
                    (b, v) -> setValue(v));

        } 

    public BinderValidationStatus<String> getStatus() {
    return status;
    }

    public void setStatus(BinderValidationStatus<String> status) {
    this.status = status;
    }

    public boolean validate() {
     BinderValidationStatus<String> status = binder.validate();
     return status.isOk();
    }

    }

}

I have also an TextEditorConfiguration added:

public class TextFieldConfiguration implements EditorConfiguration {

    private Validator<String> validator;
    private int validated;

    public TextFieldConfiguration(Validator<String> validator) {
        this.validator = validator;

    }
    public TextFieldConfiguration() {
        this.validator = null;
    }
    public Validator<String> getValidator() {
        return validator;

    }
    public int getValidated() {
        return validated;
    }
    public void setValidated(int validated) {
        this.validated = validated;
    }
}

In my case there are plenty of editors like DateEditor and so on. UI Valtidation works well. Since one month I can not find a way how to connect it to submit button to prevent send a form.

In the form class I have defined all questions for example:

question = new AseQuestion(AseQuestionId.DATE_OF_NOTIFICATION, EditorType.DATE_EDITOR);
question.setDescription(
        "When it happend?");
question.setEditorConfiguration(new DateFieldConfiguration(dateRequiredValidator(), dateNotAllowedValidator()));
return question;
question = new AseQuestion(AseQuestionId.QUESTION2, EditorType.STRING_EDITOR);   
question.setDescription("
            "Write something");
private Validator<String> textRequiredValidator() {
    return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
             "It cannot be empty!!!");

And the class where I have a submit button

public class QuestionWindow extends Window {
    @Autowired
    private transient VaadinStringEditor editor;

    private Button createSaveButton() {
        Button saveButton = new Button(i18n.getWithDefault("newAseQuestions.save", "Übernehmen"));

        saveButton.addClickListener(e -> {
            if (editor.getBinder.validate()) {
                Notification.show("This is the caption OK", "This is the description",
                        Notification.Type.HUMANIZED_MESSAGE);
            } else {
                Notification.show("This is the caption", "This is the description",
                        Notification.Type.HUMANIZED_MESSAGE);
                System.out.println("kurwa");
            }

            saveAse();
        });
        return saveButton;
    }

Upvotes: 0

Views: 933

Answers (1)

Tom
Tom

Reputation: 1027

OK lets assume we haven this POJO:

public class Person {
    private String firstname;
    private String lastname;

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

}

And we want to edit it. So we build the following form:

public class Form {
    private TextField firstname;
    private TextField lastname;

    private Binder<Person> binder = new Binder<>();

    void bindFields() {
        binder.forField(firstname).withValidator(textRequiredValidator())
            .asRequired("Mandatory").bind(Person::getFirstname, Person::setFirstname);
        binder.forField(lastname).withValidator(textRequiredValidator())
            .asRequired("Mandatory").bind(Person::getLastname, Person::setLastname);
    }

    public void setDatasource(Person person) {
        binder.setBean(person);
    }

    private Validator<String> textRequiredValidator() {
        return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
            "It cannot be empty!!!");
    }

    public boolean validate() {
        BinderValidationStatus<Person> status = binder.validate();
        return status.isOk();
    }
}

In order to use this form we need to call bindFields first (e.g. constructor, init).

Than a controller or so calls setDatasource with the person we want to edit.

After this the user can fill or edit the form and when the user finishes the status of the form can be retrieved via validate.

If you need the errors from the fields you get them from the BinderValidationStatus.

For more information look at https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html

Upvotes: 2

Related Questions