3

テーブルの編集モードに入ったときに、ユーザーが検証制約の範囲外になるとすぐに、データ検証の感嘆符​​アイコン (!) が表示されるようにします。

まず、いくつかの注意事項:

  • 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 キーを押すか、そのフィールドをぼかす/フォーカスを外しても、エラーの兆候がまったく表示されないことです。何かが間違っていることを確認するには、フィールドにマウスオーバーする必要があります。

私の質問は2つ折りです...

  1. フィールドが無効な場合に感嘆符アイコンを表示するにはどうすればよいですか? (これは、テーブルにない通常の TextField で機能します)
  2. 無効なフィールド (アイコンを表示) からすぐに応答を取得する方法はありますか (つまり、Enter キーを押したり、問題のフィールドをぼかしたりフォーカスを外したりすることなく、5 文字未満を入力した直後に)。

両方の質問に答えていただければ幸いです。=)

前もって感謝します!

4

1 に答える 1

3
  1. キャプション、必須インジケーター (赤いアスタリスク) と、ここで最も重要なエラー インジケーター (感嘆符) は、コンポーネント自体ではなく、コンポーネントを含むレイアウトによって実際に提供されます。編集可能なコンポーネントがテーブルに表示される場合、それらはレイアウトなしで表示されます。そのため、エラー インジケータは表示されません。

    この円を四角にしようとしている場合は、編集可能なフィールドのラッパーとして CustomField を作成することを検討します。その CustomField 内で、ラップされた/デリゲート フィールドが無効になると、エラー インジケーターが表示されます。私はこれを試していません - テーブルで編集可能なフィールドをまったく使用していません - しかし、かなり簡単に実行できるはずです。

  2. FieldFactory のフィールドに TextChangeListenerを追加し、リスナーで field.validate() を呼び出します。ただし、field.getValue() 値は通常、ぼかし/フォーカス解除するまで変更されないことに注意してください。そのため、リスナーで field.setValue(event.getText()) を実行しない限り、バリデーターは古い値を検証します。詳細については、Vaadin フォーラムのこの投稿を参照してください。

これは、検証ラッパーに対して私が意図したようなものです - それを使用しようとはしませんでした。initComponent が FormLayout 内のフィールドを返すだけで、探しているアイコンが得られるはずです。(ValidatingWrapper からデリゲートに、私が持っているよりも多くのメソッドをデリゲートする必要があるかもしれませんが、簡単に見てみると、これで十分かもしれません。)

次に、フィールドを tableFieldFactory でラップします (2 番目のコード ブロック)。

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);
  }
});
于 2013-07-31T08:13:51.650 に答える