如何确定是否将DateField在Vaadin 8
是有效的,我有:如何确定是否将DateField在Vaadin 8
DateField dateField = new DateField("Date");
Button submitButton = new Button("Submit");
submitButton.addClickListener(click -> handleClickListener());
其中handleClickListener()
我希望阻止提交如果在DateField
验证错误。我知道我可以使用一个活页夹,然后binder.validate()
但这种形式没有支持对象,我只是想要一个简单的形式。我怎么可以这样做:
if(!dateField.isValid())
// no further processing
else
// process
我找不到允许检查,看看是否在输入值是有效的DateField
中的任何代码。显然in Vaadin 7 you could !dateField.validate()
which would throw an exception,但这不再是似乎是这种情况...
我也知道有可能做dateField.isEmpty()
或测试为null,但这是行不通的,因为一个值是不需要的。换句话说,它可以是空的,或者如果你输入一个值,那么它必须是一个有效的条目。
这已被问过好几次了,据我所知,不可能在没有活页夹的情况下添加校验器。您可以检查this answer以了解功能和谐振的全面描述。
也有关于Vaadin forum和github的讨论,并且2个主要建议是使用活页夹或值更改侦听器(您在其中手动调用验证程序)。然而,后一种解决方案似乎并不奏效,我怀疑这是因为价值变化事件只有在实际值发生变化时才会触发,当您输入无效时可能不会发生这种情况,但我没有花太多时间进行调查。
latest suggestion on github请求binder.noBind()
方法来促进这些情况,但在实现该方法之前,您可以使用类似于以下代码示例的方法。我也讨厌使用字段的值绑定的想法,所以我用就没有setter & 没有消气概念:
public class DateFieldWithValidator extends VerticalLayout {
public DateFieldWithValidator() {
// date field with binder
Binder<LocalDate> binder = new Binder<>();
DateField dateField = new DateField("Date");
binder.forField(dateField)
.asRequired("Please select a date")
.bind(No.getter(), No.setter());
// validity status
TextField validityField = new TextField("Status:", "N/A");
validityField.setReadOnly(true);
validityField.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
validityField.setWidth("100%");
// submit button
Button submitButton = new Button("Submit");
submitButton.addClickListener(event -> {
BinderValidationStatus<LocalDate> status = binder.validate();
if (status.isOk()) {
validityField.setValue("OK: " + dateField.getValue().toString());
} else {
validityField.setValue("KO: " + status.getValidationErrors().stream().map(ValidationResult::getErrorMessage).collect(Collectors.joining(",")));
}
});
addComponents(dateField, submitButton, validityField);
}
// convenience empty getter and setter implementation for better readability
public static class No {
public static <SOURCE, TARGET> ValueProvider<SOURCE, TARGET> getter() {
return source -> null;
}
public static <BEAN, FIELDVALUE> Setter<BEAN, FIELDVALUE> setter() {
return (bean, fieldValue) -> {
//no op
};
}
}
}
结果:
稍后更新:
我一直在想更多,如果它是可以接受的,你可以禁用提交按钮,如果该值为空或解析错误发生无效值。这可以通过如下的ValueChangeListener
和ErrorHandler
来轻松实现。
或者,您可以将异常消息保存在变量中,并且当您单击该按钮时,检查是否存在错误消息或值为空,按此顺序,因为如果输入的日期无效,则字段的值将被设置为空。
public class DateFieldWithValidator extends VerticalLayout {
public DateFieldWithValidator() {
DateField dateField = new DateField("Date");
Button submitButton = new Button("Submit");
submitButton.setEnabled(false);
submitButton.addClickListener(event -> Notification.show("Selected date: " + dateField.getValue()));
dateField.setRequiredIndicatorVisible(true);
dateField.setErrorHandler(event -> submitButton.setEnabled(false));
dateField.addValueChangeListener(event -> submitButton.setEnabled(event.getValue() != null));
addComponents(dateField, submitButton);
}
}
结果:
即使你说你不希望使用一个支持对象,我会建议使用Binder
反正。@Morfic提供的No
类在我看来非常出色(我倾向于在许多验证实现中重用这个)。
所以我会做的是在你的粘结剂添加addStatusChangeListener
和启用/禁用有按钮:
binder.addStatusChangeListener(event -> {
if (event.hasValidationErrors()) {
submitButton.setEnabled(false);
} else {
submitButton.setEnabled(true);
}
});
省略Binder
对象的实例,因为@Morfic在他的回答提供了一个很好的例子已经。
我之所以建议使用的Binder
是因为Vaadin suggests to use it for validation,你不需要难以维持值变化监听,你可以很容易地扩大与新Validator
是你绑定如果需要的话以后。也许你会希望在一个点上将该字段绑定到一个对象上。
如何使用'Binder'(https://vaadin.com/api/8.0.1/com/vaadin/data/Binder.html)? 'Binder'带有'validate()'和'isValid()'方法。 – Thibstars
有时候,Binder不起作用。例如,我的表单可能没有POJO等,也许我只是使用表单对标签进行快速计算,而不想用任何东西来支持它。 –