我目前正在使用Vaadin 7.3+,并希望在文本字段中验证用户实时输入。
这是我到目前为止所尝试的:
textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
textField.setNullRepresentation("");
textField.addTextChangeListener(new FieldEvents.TextChangeListener() {
@Override
public void textChange(FieldEvents.TextChangeEvent event) {
for (Validator v : textField.getValidators()) {
try {
v.validate(event.getText());
} catch (InvalidValueException e) {
log.warn("validation error: " + e.getMessage() + " and value was: {}", event.getText());
}
}
}
});
问题在于,虽然正在执行所有验证器并且正在进行验证,但是在焦点离开该字段之前不会呈现红色错误指示符,即用户点击进入或点击其他地方。我尝试添加textField.markAsDirty
,但这不起作用。有谁知道这个问题的解决方案?或者更好的解决方案是在文本字段上创建实时验证器?
提前感谢您的时间和意见: - )
答案 0 :(得分:2)
Vaadin核心的验证器不适合在打字时工作,这对于RIA框架来说是一种耻辱。希望在即将推出的版本中修复此问题。今天使用核心组件使其运行良好有点棘手,但可行。如果服务器和客户端之间存在一些延迟,您自己的解决方案可能会出现一些UX问题 - 如果用户在执行验证程序时再次重新键入,则游标可能会跳转到非预期的位置。我在Viritin add-on中已经做了很多工作。通过将其AbstractForm(或原始MBeanFieldGroup)与MTextField一起使用,这应该可以很好地工作,无需任何配置。您可以尝试使用例如this example
答案 1 :(得分:1)
这里的问题是,事件发送文本,但实际上并没有修改输入的值。解决这个问题最简单的方法就是设定价值。 e.g。
addTextChangeListener(new FieldEvents.TextChangeListener() {
@Override
void textChange(FieldEvents.TextChangeEvent event) {
final textField = event.source as TextField
textField.value = event.text
}
})
这只会触发字段和验证器的更改,并且所有内容都会按预期进入客户端。
正如您在评论中所述,应保留光标位置。您可以使用您需要的任何方式验证事件中的文本。这里的关键点是,只需设置字段的componentError
即可获得该字段的误差。
@Override
void textChange(FieldEvents.TextChangeEvent event) {
final tf = event.source as TextField
try {
tf.validate(event.text) // this works in groovy! not java.
tf.setComponentError(null)
}
catch (InvalidValueException e) {
tf.setComponentError(new SystemError(e))
}
}
答案 2 :(得分:1)
这个直接的解决方案似乎工作正常,虽然它非常不优雅。
textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
textField.setNullRepresentation("");
textField.addTextChangeListener(new FieldEvents.TextChangeListener() {
@Override
public void textChange(FieldEvents.TextChangeEvent event) {
try {
textField.setValue(event.getText());
// workaround cursor position problem
textField.setCursorPosition(event.getCursorPosition());
textField.validate();
} catch (InvalidValueException e) {
log.warn("validation error: " + e.getMessage() + " and value was: {}", delegate.getValue());
}
}
});
答案 3 :(得分:0)
Take a look。如果我说得对,那么将你的领域设置为立即模式应该没问题。有时建议允许空值以避免不必要的警告。
TextField field = new TextField("Name");
field.addValidator(new StringLengthValidator(
"The name must be 1-10 letters (was {0})",
1, 10, true));
field.setImmediate(true);
field.setNullRepresentation("");
field.setNullSettingAllowed(true);