【问题标题】:Form validation with Binder使用 Binder 进行表单验证
【发布时间】:2017-10-19 07:20:17
【问题描述】:

如何在 Vaadin 8 中通过发送所有表单数据来完成验证?不幸的是,我不了解活页夹的概念:(我写了一个字段验证,但现在呢?它起作用了。我的用户看到我什么时候要求他填写一个字段,但是有没有简单的方法来验证我的所有表单?我怎么能“告诉”到我的保存按钮,我的表单是有效的?

在我的编辑器中我定义了一个验证器

@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();
    }

    }

}

我还添加了一个 TextEditorConfiguration:

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;
    }
}

就我而言,有很多编辑器,例如 DateEditor 等。 UI 验证效果很好。由于一个月以来我找不到一种方法如何将它连接到提交按钮以防止发送表单。

在表单类中我定义了所有问题 例如:

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!!!");

还有我有提交按钮的类

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;
    }

【问题讨论】:

    标签: java validation vaadin vaadin7 vaadin8


    【解决方案1】:

    好吧,假设我们有这个 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;
        }
    
    }
    

    我们想要编辑它。 所以我们构建如下形式:

    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();
        }
    }
    

    为了使用这个表单,我们需要首先调用 bindFields(例如构造函数,init)。

    与我们要编辑的人一起调用setDatasource的控制器。

    在此之后,用户可以填写或编辑表单,当用户完成表单的状态时,可以通过 validate 检索。

    如果您需要从 BinderValidationStatus 获取的字段中的错误。

    更多信息请查看https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html

    【讨论】:

    • 感谢您提供了这个很好的示例,但在我的情况下,我没有使用任何对象进行绑定:(我使用了类似 binder.forField(this).withValidator(validator).asRequired("Mandatory") .bind(s -> getValue(), (b, v) -> setValue(v)); 所以我的问题是如何对我的案例进行验证;)
    • 您可以使用我的示例中的验证方法从 VaadinStringEditor 获取状态。也许您可以通过表格提供您想要实现的目标,以便我可以给您更好的答案。
    • @Tom 您可以在validate() 方法中使用内联返回。 @Anna K 如果您希望在不绑定到实际对象的情况下进行验证,您可能想看看这个答案:stackoverflow.com/a/46607223/3403011
    • @Tom 我更新了我的问题。你能帮我解决这个问题吗?我已经尝试了一个月 :( 到现在我只实现了 UI Validation 但如何将它连接到提交按钮
    • @Thibstars 你是对的,但我出于教育目的使用 BinderValidationStatus 迈出了一步。该链接看起来像 Anna K 想要实现的目标
    猜你喜欢
    • 2018-05-11
    • 2015-06-25
    • 2017-02-04
    • 2015-07-31
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多