0

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;
    }
Anna K
  • 1,666
  • 4
  • 23
  • 47

1 Answers1

2

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

Tom
  • 977
  • 11
  • 18
  • Thank you for this great example but in my case Im not using any object to bind :( Im using something like this binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(), (b, v) -> setValue(v)); So my problem is how to do validation with my case ;) – Anna K Oct 19 '17 at 14:49
  • Than you can use the validate mehtod from my example to get the status from the VaadinStringEditor. Maybe you can provide the goal you want to achieve with the form so i can give you a better answer. – Tom Oct 19 '17 at 16:23
  • @Tom You could use an inline return in your `validate()` method. @Anna K if you are looking to validate without binding to an actual object, you might want to take a look at this answer: https://stackoverflow.com/a/46607223/3403011. – Thibstars Oct 20 '17 at 06:24
  • @Tom I updated my question. Could you please help me with that problem. I have been trying to do for one month :( Till now I achieved only UI Validation but how to connect it to the submit button – Anna K Oct 20 '17 at 07:35
  • 1
    @Thibstars You are right but i made the step with the BinderValidationStatus for education purpose. The link looks like what Anna K want to achive – Tom Oct 20 '17 at 08:05
  • @Anna K write a validate method in your VaadinStringEditor and then acces it on button click. It is nicely shown in the link from Thibstars – Tom Oct 20 '17 at 08:13
  • @Tom I have updated my code. I added BiderValidationStatus getter but I get Nullpointexception when I try to get this info from VaadinStringEditor :( Could you please help me to manage it – Anna K Oct 20 '17 at 08:22
  • @Tom it doesnt work, Have I changed it right? editor.getBinder.validate() – Anna K Oct 20 '17 at 09:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157135/discussion-between-tom-and-anna-k). – Tom Oct 20 '17 at 12:31