我在验证 DateFields 时遇到了一些麻烦。在我的应用程序中,我有一个带有 DateField 属性的表,用户应该能够通过按下编辑按钮来编辑它。我还有一个提交字段的确定按钮和一个丢弃它们的取消按钮。
这是我想要实现 的(当然有一些必须遵循的简洁规则):
- 首先,日期只能更改为当天最多 9999-12-31。
- 其次,我希望验证是动态的(按您的类型)
- 原始日期(进入编辑模式时已经在表格中的日期)可以是任何日期,您应该能够按原样提交这些日期,即使它们是过去的。
- 如果您将日期更改为无效日期(您仍然可以“手动”执行此操作,即直接在字段中,而不是在日期选择器中)或在 DateField 中输入无效字符,应显示错误图标和消息,在您输入有效日期之前,不允许您提交更改。
- 如果您将日期更改为无效日期(显示错误图标),然后更改为有效日期,错误图标应该会消失。
我设法实现的当前行为执行以下操作:
- 允许“原始日期” - 好的
- 允许更改为有效日期 - 确定
- 当更改为无效日期(可以“手动”完成,不使用日期选择器)并在字段中按 Enter 时,该字段立即重置为原始日期,但仍然显示错误图标 - 不正常
- 输入无效字符(可以“手动”完成,不使用日期选择器)并在字段中按 Enter 时,提交时会抛出 NPE,也不会显示错误图标 - 不正常
- 当更改为无效日期并在字段中按 enter 并返回到有效日期并在字段中按 enter 时,错误图标仍然存在 - 不正常
- 当更改为无效日期并按 OK(即 commit())时,该字段首先重置为原始日期并提交更改(即对该字段没有任何更改) - 不正常
现在,我尝试实现一个包装器,以便我可以监听值的变化,但是 DateField 没有像 TextField 那样的方便方法(例如 setTextChangeEventMode 和 setTextChangeTimeout)。我覆盖 valueChange 以解决一些问题,但它似乎只在您更改为有效日期时才被调用,而不是在您更改为无效日期时(您还必须在每次不使用日期选择器时按 enter) ...相反,另一个 validate() 在后台被调用,一直重置 setValidationVisible() 。
我什至尝试创建一个 CustomDateRangeValidator,但发现它没有多大帮助。
请帮我弄清楚这一点,我现在已经尝试了很多东西,但我已经没有选择了。
这是我的 createField 方法:
createField(){
// some more code up here...
if (propertyId.equals("Valid From")) {
dField.setImmediate(true);
dField.setRangeStart(new Date());
dField.setRangeEnd(dateUtil.getDate(9999, 12, 31));
dField.setDateOutOfRangeMessage("Date out of range!");
@SuppressWarnings({ "unchecked", "rawtypes" })
TableDataValidatingWrapper<TextField> wField = new TableDataValidatingWrapper(dField);
return wField;
}
// some more code down here...
}
...这是我的包装:
public class TableDataValidatingWrapper<T> extends CustomField<T> {
private static final long serialVersionUID = 1L;
protected Field<T> delegate;
public TableDataValidatingWrapper(final Field<T> delegate) {
this.delegate = delegate;
if (delegate instanceof DateField) {
final DateField dateField = (DateField) delegate;
dateField.setCaption("");
dateField.setImmediate(true);
dateField.setInvalidAllowed(false);
dateField.setInvalidCommitted(true);
dateField.setValidationVisible(false);
dateField.addValueChangeListener(new ValueChangeListener() {
private static final long serialVersionUID = 1L;
@Override
public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
try {
dateField.validate();
dateField.setValidationVisible(false);
} catch (InvalidValueException ive) {
//handle exception
} catch (Exception e) {
//handle exception
}
}
});
}
}
//some other overridden methods here...
}