如何在 Vaadin 的文本字段上创建实时验证器?
How to create a real time validator on a text field in Vaadin?
我目前使用的是 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
但这没有用。有谁知道这个问题的解决方案?或者一般来说有更好的解决方案来在文本字段上创建实时验证器?
提前感谢您的宝贵时间和意见:-)
这里的问题是,事件发送了文本,但实际上并没有修改输入的值。解决这个问题的最简单方法是设置值。例如
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))
}
}
这个直接的变通解决方案似乎工作正常,尽管它很不优雅。
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());
}
}
});
Vaadin 核心中的验证器并非设计为在键入时工作,这对于 RIA 框架来说是一种耻辱。这有望在即将发布的版本中得到修复。今天让它与核心组件一起工作有点棘手,但可行。如果您的服务器和客户端之间存在一些延迟,您自己的解决方案可能会出现一些用户体验问题 - 如果用户在执行验证器时再次开始重新输入,则光标可能会跳到意想不到的位置。我在 Viritin add-on. By using its AbstractForm (or raw MBeanFieldGroup) together with MTextField this should work pretty well and without any configuration. You can try that solution with e.g. this example.
中为此做了很多工作
Take a look 在 Vaadin 文档中。如果我没看错,将您的字段设置为即时模式应该没问题。有时建议允许空值以避免不必要的警告。
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);
我目前使用的是 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
但这没有用。有谁知道这个问题的解决方案?或者一般来说有更好的解决方案来在文本字段上创建实时验证器?
提前感谢您的宝贵时间和意见:-)
这里的问题是,事件发送了文本,但实际上并没有修改输入的值。解决这个问题的最简单方法是设置值。例如
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))
}
}
这个直接的变通解决方案似乎工作正常,尽管它很不优雅。
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());
}
}
});
Vaadin 核心中的验证器并非设计为在键入时工作,这对于 RIA 框架来说是一种耻辱。这有望在即将发布的版本中得到修复。今天让它与核心组件一起工作有点棘手,但可行。如果您的服务器和客户端之间存在一些延迟,您自己的解决方案可能会出现一些用户体验问题 - 如果用户在执行验证器时再次开始重新输入,则光标可能会跳到意想不到的位置。我在 Viritin add-on. By using its AbstractForm (or raw MBeanFieldGroup) together with MTextField this should work pretty well and without any configuration. You can try that solution with e.g. this example.
中为此做了很多工作Take a look 在 Vaadin 文档中。如果我没看错,将您的字段设置为即时模式应该没问题。有时建议允许空值以避免不必要的警告。
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);