表字段中未显示验证图标

时间:2013-07-30 14:41:51

标签: vaadin vaadin7

当我进入我的表的编辑模式时,我希望在用户超出任何验证限制的范围时立即显示数据验证感叹号图标(!)。 < / p>

首先,几个笔记:

  • 我使用的是Vaadin 7,因此Bean Validation插件遗憾地无法工作。
  • 数据验证按预期工作。

现在,我有一个完美的工作表,我正在使用BeanItemContainer来保持我的Person bean。

表和TableFieldFactory的代码如下所示:

table.setContainerDataSource(buildContainer());
table.setTableFieldFactory(new TableFieldFactory() {
    @Override
    public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
        TextField field = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId,
                uiContext);
        field.setImmediate(true);
        if (propertyId.equals("firstName")) {
            field.addValidator(new BeanValidator(Person.class, "firstName"));
        }
        return field;
    }
});

Person bean如下所示:

public class Person {

    @Size(min = 5, max = 50)
    private String firstName;

    ... setters + getters...
}

问题在于,当我在firstName字段中键入内容然后按enter或blur / unfocus该字段时,不会显示任何错误指示。我必须将鼠标悬停在该字段上以查看出现问题。

我的问题是两个折叠......

  1. 如何在字段显示时显示感叹号图标 无效? (这适用于表中的普通TextField)
  2. 有没有办法从无效字段获得立即响应 (显示图标)(即在您输入5个字符后立即, 无需按下输入或模糊/不聚焦该字段 问题)。
  3. 如果我能回答两个问题,那就太好了! =)

    提前致谢!

1 个答案:

答案 0 :(得分:3)

  1. 标题,必需指示符(红色星号)和 - 最重要的是 - 错误指示符(感叹号)实际上由包含组件的布局提供,组件本身。当可编辑组件显示在表格中时,它们会显示不带布局 - 这就是没有显示错误指示符的原因。

    如果我试图对这个圆圈进行平方,我会考虑创建一个CustomField作为可编辑字段的包装器 - 并且当包装/委托字段变为无效时,该CustomField中会显示错误指示符。我没试过这个 - 我根本没有在表格中使用过可编辑的字段 - 但是应该很容易做到。

  2. 在FieldFactory中的字段中添加TextChangeListener,并在侦听器中调用field.validate()。但是请注意,field.getValue()值通常不会更改直到模糊/非焦点,因此验证器将验证旧值 - 除非您执行field.setValue(event.getText())在听众中。有关详细信息,请参阅Vaadin论坛上的this post

  3. 这是我对验证包装器的意思 - 没有尝试使用它。您将看到initComponent只返回FormLayout中的字段,该字段应该为您提供您正在寻找的图标。 (您可能需要将来自ValidatingWrapper的更多方法委托给委托,但我可以快速查看这可能就足够了。)

    然后将该字段包装在tableFieldFactory(第二个代码块)

    public class ValidatingWrapper<T> extends CustomField<T> {
    
      private static final long serialVersionUID = 9208404294767862319L;
      protected Field<T> delegate;
    
      public ValidatingWrapper(final Field<T> delegate) {
        this.delegate = delegate;
    
        if (delegate instanceof TextField) {
          final TextField textField = (TextField) delegate;
          textField.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.TIMEOUT);
          textField.setTextChangeTimeout(200);
    
          textField.addTextChangeListener(new FieldEvents.TextChangeListener() {
            @Override
            public void textChange(FieldEvents.TextChangeEvent event) {
              textField.setValue(event.getText());
              textField.validate();
            }
          });
        }
      }
    
      @Override
      public Class<? extends T> getType() {
        return delegate.getType();
      }
    
      @Override
      protected Component initContent() {
        return new FormLayout(delegate);
      }
    
    
      @Override
      public Property getPropertyDataSource() {
        return delegate.getPropertyDataSource();
      }
    
      @Override
      public void setPropertyDataSource(Property newDataSource) {
        delegate.setPropertyDataSource(newDataSource);
      }
    
    }
    

    table.setContainerDataSource(buildContainer());
    table.setTableFieldFactory(new TableFieldFactory() {
      @Override
      public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
        TextField field = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId,
            uiContext);
        field.setImmediate(true);
        if (propertyId.equals("firstName")) {
          field.addValidator(new BeanValidator(Person.class, "firstName"));
        }
        return ValidatingWrapper(field);
      }
    });