如何确定 DateField 在 Vaadin 8 中是否有效
How to determine if a DateField is valid in 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
中找不到任何允许检查输入值是否有效的代码。显然 但现在似乎不再如此...
我也知道可以执行 dateField.isEmpty()
或测试 null 但这不起作用,因为不需要值。换句话说,它可以是空的,或者如果你输入一个值,那么它必须是一个有效的条目。
这个问题已经被问过好几次了,据我所知,没有活页夹就不可能添加验证器。您可以查看 以获得对该功能和共鸣的全面描述。
Vaadin forum and github 上也有讨论,2 个主要建议是使用活页夹,或手动调用验证器的值更改侦听器。但是,后一种解决方案似乎不起作用,我怀疑这是因为仅当实际值发生变化时才会触发值更改事件,而当您键入无效内容时可能不会发生这种情况,但我没有花太多时间进行调查。
latest suggestion on github 请求 binder.noBind()
方法来促进这些情况,但在该方法实现之前,您可以使用类似于以下代码示例的内容。我也讨厌使用字段绑定值的想法,所以我选择了 no setter & no getter概念:
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
};
}
}
}
结果:
稍后更新:
我想了很多,如果可以的话,你可以禁用提交按钮,如果值为 null 或对无效值发生解析错误。这可以通过 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
class 非常好(我倾向于在许多验证实现中重用它)。
所以我要做的是在你的活页夹上添加一个 addStatusChangeListener
和 enable/disable 那里的按钮:
binder.addStatusChangeListener(event -> {
if (event.hasValidationErrors()) {
submitButton.setEnabled(false);
} else {
submitButton.setEnabled(true);
}
});
省略了 Binder
对象的实例化,因为@Morfic 已经在他的回答中提供了一个很好的例子。
我建议使用 Binder
的原因是因为 Vaadin suggests to use it for validation,您不需要费力地维护值更改侦听器,并且可以轻松地使用新的 [=16= 扩展您的绑定]s 如果以后需要的话。也许你最终会想在某一时刻将字段绑定到一个对象。
我有:
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
中找不到任何允许检查输入值是否有效的代码。显然
我也知道可以执行 dateField.isEmpty()
或测试 null 但这不起作用,因为不需要值。换句话说,它可以是空的,或者如果你输入一个值,那么它必须是一个有效的条目。
这个问题已经被问过好几次了,据我所知,没有活页夹就不可能添加验证器。您可以查看
Vaadin forum and github 上也有讨论,2 个主要建议是使用活页夹,或手动调用验证器的值更改侦听器。但是,后一种解决方案似乎不起作用,我怀疑这是因为仅当实际值发生变化时才会触发值更改事件,而当您键入无效内容时可能不会发生这种情况,但我没有花太多时间进行调查。
latest suggestion on github 请求 binder.noBind()
方法来促进这些情况,但在该方法实现之前,您可以使用类似于以下代码示例的内容。我也讨厌使用字段绑定值的想法,所以我选择了 no setter & no getter概念:
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
};
}
}
}
结果:
稍后更新:
我想了很多,如果可以的话,你可以禁用提交按钮,如果值为 null 或对无效值发生解析错误。这可以通过 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
class 非常好(我倾向于在许多验证实现中重用它)。
所以我要做的是在你的活页夹上添加一个 addStatusChangeListener
和 enable/disable 那里的按钮:
binder.addStatusChangeListener(event -> {
if (event.hasValidationErrors()) {
submitButton.setEnabled(false);
} else {
submitButton.setEnabled(true);
}
});
省略了 Binder
对象的实例化,因为@Morfic 已经在他的回答中提供了一个很好的例子。
我建议使用 Binder
的原因是因为 Vaadin suggests to use it for validation,您不需要费力地维护值更改侦听器,并且可以轻松地使用新的 [=16= 扩展您的绑定]s 如果以后需要的话。也许你最终会想在某一时刻将字段绑定到一个对象。