JSFでの通常の検証では、単一の要素しか検証できないため、この制限を回避する必要があります。JSFを使用してクロスフィールド検証を行うには、少なくとも2つの方法があります。
バリデーターを最後の要素(または最後の要素の後ろに隠された要素)に適用して、カスタムのバリデーター/メソッドを定義し、要素を検索して検証を行うことができます。
PostValidateEvent
次のようなリスナーを登録します<f:event type="postValidate" listener="#{myValidationBean.validateDates}"/>
。残りの手順は、1とまったく同じです。
検証方法での要素ルックアップ:
UIComponent source = event.getComponent();
UIInput minInput = (UIInput) source.findComponent("minYear");
UIInput maxInput = (UIInput) source.findComponent("maxYear");
要素の値にアクセスします。
int minYear = ((Integer)minInput.getLocalValue()).intValue();
int maxYear = ((Integer)maxInput.getLocalValue()).intValue();
編集:おっと、検証メッセージの部分を忘れました。
String valMsg = "maxYear cannot be less than minYear";
FacesContext.getCurrentInstance().addMessage(source.getClientId(), new FacesMessage(valMsg, valMsg));
EDIT2:イベントリスナーを使用して検証し、検証が失敗した場合は、モデルに無効なデータが設定されないように、すぐに応答レンダリングフェーズに進むことをお勧めします。これを行うcontext.renderResponse();
には、エラーメッセージをディスパッチした後に呼び出します。
EDIT3:システムイベントはJSF2で導入されましたが、最初のアプローチはJSF1.xで実行可能である必要があります。JSFによって検証メソッドに渡されるコンテキストとコンポーネントを取得するため、ルックアップ時とメッセージディスパッチ時の詳細はわずかに異なります。
public void validateMulti(FacesContext context, UIComponent component, Object value){
...
UIInput minInput = (UIInput) component.findComponent("minYear");
...
context.addMessage("minYear", new FacesMessage(valMsg, valMsg));
...