java - 验证 vaadin 组合框自定义输入(仅限整数)
问题描述
我有一个带有组合框的输入表单,它显示整数值。我希望用户能够向此组合框添加新的整数值。我需要验证输入是否只是数字(而不是字母) - 如果它不是一个有效的整数,我想显示一条错误消息。
对于文本字段,我很快就明白了——即使输入“错误”输入,我也会收到一条错误消息!但是我找不到与 addCustomValueSetListener 结合使用的组合框的解决方案。
我正在使用 Vaadin 14.1.21 和 Java JDK+JRE 1.8。
现在,如果我输入带有字母的自定义值,我不会在框下方显示错误消息,并且当我想“保存”它/将其存储在数据库中时,它只是默默地忽略输入值。
public class MyForm extends Div {
private TextField tf;
tf =new TextField("TF");
tf.setWidth("100%");
tf.setRequired(true);
tf.addThemeVariants(TextFieldVariant.LUMO_ALIGN_RIGHT);
tf.setValueChangeMode(ValueChangeMode.EAGER);
private ComboBox<Integer> combo_int;
combo_int= new ComboBox<>();
combo_int.setItems(114, 12383, 65432189);
combo_int.setLabel("Some ID");
combo_int.addCustomValueSetListener(
event -> combo_int.setValue(Integer.parseInt(event.getDetail()))
// since I need to parse new values here, I cannot use a validator upon binding
);
binder = new BeanValidationBinder<>(MyData.class);
binder.forField(tf)
.withNullRepresentation("")
.withConverter(new StringToIntegerConverter("needs to be integer!"))
.bind("tf_data_integer");
binder.forField(combo_int)
.bind("integer_data");
}
解决方案
所以我想出了一个非常肮脏的 McGyver 解决方案......但它仍然不能 100% 工作。
主要问题是:
- 我必须在 addCustomValueSetListener 中解析(并因此验证)自定义输入
- 我无法在 bean-binder 上执行此操作,因为自定义输入以字符串的形式出现,而 bean-binder 需要一个 Integer
- 使用 withConverter(StringToInteger) 不起作用,因为我仍然希望能够从下拉菜单中选择一个整数项。
所以我不得不
- 建立我自己的警告标签
- 在表单中显示的对象之间切换时手动重置标签
- 使用 setInvalid 突出显示错误的输入并在之后重置它
- 劫持 Validator 以重置 status_label(如果用户在选择错误的下拉菜单后使用下拉菜单,则修复标签剩余的问题 - 标签保持...)
我仍然有 binder.hasChanges() 没有将无效输入注册为更改的问题,因为我们事先在解析器中捕获了它并且它永远不会到达活页夹。
也许我明天也会找到解决方案。
public class MyForm extends Div {
private Label status_label = new Label();
private TextField tf;
tf =new TextField("TF");
tf.setWidth("100%");
tf.setRequired(true);
tf.addThemeVariants(TextFieldVariant.LUMO_ALIGN_RIGHT);
tf.setValueChangeMode(ValueChangeMode.EAGER);
private ComboBox<Integer> combo_int;
combo_int= new ComboBox<>();
combo_int.setItems(114, 12383, 65432189);
combo_int.setLabel("Some ID");
combo_int.addCustomValueSetListener((event -> {
if (isInteger(event.getDetail())){
status_label.setText(""); // reset on success
warengruppen_id.setValue(Integer.parseInt(event.getDetail()));
warengruppen_id.setInvalid(false);
} else {
status_label.setText("Custom Format-Error!"); // set to error
status_label.getStyle().set("color", "red");
combo_int.setInvalid(true); // red background coloring
}
}
);
binder = new BeanValidationBinder<>(MyData.class);
binder.forField(tf)
.withNullRepresentation("")
.withConverter(new StringToIntegerConverter("needs to be integer!"))
.bind("tf_data_integer");
binder.forField(combo_int).
withValidator(event -> {
// we highjack the Validator to reset the field on correct input
status_label.setText("");
return true; // never raise the validator message
}, "")
.withNullRepresentation(null)
.bind("integer_data");
}
推荐阅读
- django - 从 django 管理页面重新启动服务的选项
- c++ - 关于别名模板
- sql-server - 与 SQL Server 连接执行期间 vb.net 中的登录错误
- c++ - C++ 使用 qfile 写入资源文件(QIODevice::write (QFile,"x"): device not open)
- twitter-bootstrap - Bootstrap 4 Dropdown Navbar 使用 Plus 和 Minus Fontawesome 5 更改插入符号
- elasticsearch - Elasticsearch - 使用通配符的自定义词干覆盖
- asp.net-mvc - 如何使用 Unity 将依赖项注入 MVC 操作
- excel - VBA循环代码并让它识别要在Excel中复制的多个工作表?
- pyspark - Pyspark java.net.SocketTimeoutException:接受超时
- powershell - 从过期日期Powershell计算AD密码年龄