2

私の .jsp には、開始年と終了年を示す 2 つの selectOneMenu 項目があります。選択した開始年が終了年よりも大きい場合、エラーメッセージを表示したいと思います。どうすればこれを解決できますか?

<h:selectOneMenu id="minYear" value="#{statistics.minYear}" style="width: 75px">
    <f:selectItems value="#{statistics.yearValues}" />
</h:selectOneMenu>

<h:selectOneMenu id="maxYear" value="#{statistics.maxYear}" style="width: 75px">
    <f:selectItems  value="#{statistics.yearValues}"/>
</h:selectOneMenu>

バッキング Bean には、範囲が有効かどうかにかかわらず true/false を返すメソッドがあります。

public boolean isYearValid() {
    return (getMaxYear() >= getMinYear());
}
4

1 に答える 1

4

JSFでの通常の検証では、単一の要素しか検証できないため、この制限を回避する必要があります。JSFを使用してクロスフィールド検証を行うには、少なくとも2つの方法があります。

  1. バリデーターを最後の要素(または最後の要素の後ろに隠された要素)に適用して、カスタムのバリデーター/メソッドを定義し、要素を検索して検証を行うことができます。

  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));
  ...
于 2012-06-04T13:09:45.717 に答える