3

DateFields の検証に問題があります。私のアプリケーションには、ユーザーが編集ボタンを押して編集できる DateField プロパティを持つテーブルがあります。また、フィールドをコミットする OK ボタンと、それらを破棄するキャンセル ボタンもあります。

これが私が達成したいことです (もちろん、従わなければならないきちんとしたルールがいくつかあります):

  • まず、日付は9999-12-31 までの現在の日付にのみ変更できます。
  • 第二に、検証を動的にすることをお勧めします (入力時)。
  • 元の日付 (編集モードに入ったときに既にテーブルにある日付) は任意の日付にすることができ、過去のものであっても、これらをそのままコミットできるはずです。
  • 日付を無効な日付に変更した場合 (日付ピッカーではなく、フィールドで直接「手動で」行うことができます)、または DateField に無効な文字を入力すると、メッセージと共にエラー アイコンが表示されます。有効な日付を入力するまで、変更をコミットできません。
  • 日付を無効な日付 (エラー アイコンが表示されている) に変更してから有効な日付に変更すると、エラー アイコンは表示されなくなります。

私がなんとか実装した現在の動作 は、次のことを行います。

  • 「元の日付」を許可 - OK
  • 有効な日付への変更を許可 - OK
  • 無効な日付に変更した場合 (日付ピッカーを使用せずに「手動で」行うことができます)、フィールドで Enter キーを押すと、フィールドはすぐに元の日付にリセットされますが、エラー アイコンは表示されたままです - OK ではありません
  • 無効な文字 (日付ピッカーを使用せずに「手動で」行うことができます) を入力してフィールドに Enter キーを押すと、コミット中に NPE がスローされ、エラー アイコンも表示されません - OK ではありません
  • 無効な日付に変更してフィールドで Enter キーを押し、有効な日付に戻ってフィールドで Enter キーを押すと、エラー アイコンが表示されたままになります - OK ではありません
  • 無効な日付に変更して OK を押すと (つまり commit())、フィールドは最初に元の日付にリセットされ、変更 (つまり、フィールドにまったく変更がない) がコミットされます - OK ではありません

さて、値の変化をリッスンできるようにラッパーを実装してみましたが、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...
}
4

1 に答える 1