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...
}