17

2 つの日付 (StartDate と EndDate) を比較し、一方が他方より前かどうかを確認したいと考えています。最も簡単な解決策は、バッキング Bean で実行し、メソッドを「短絡」することです。

ただし、この検証は他のフォーム検証と同時には行われません。たとえば、(日付以外に) 検証が必要な別のフィールドがあり、無効な入力がある場合、その特定のフィールドのメッセージのみが表示されます。他のフィールドが有効な場合にのみ、バッキング Bean に基づいて日付の検証が行われます。

誰にも解決策がありますか?

4

4 に答える 4

36

ただし、この検証は他のフォーム検証と同時には行われません。

実際、バッキング Bean のアクション メソッドは、入力の検証を実行するためのものではありません。


誰にも解決策がありますか?

仕事に適したツールを使用してください。通常の を使用しますValidator

@FacesValidator("dataRangeValidator")
public class DateRangeValidator implements Validator {
    // ...
}

ただし、単一のバリデーターで複数の入力値を検証することは、実際には別の話です。validate()基本的に、他のコンポーネントまたはその値を取得してメソッドの実装に渡す必要があります。最も単純な形式では、これに使用できます<f:attribute>。を使用して日付を選択すると仮定すると<p:calendar>、具体的なキックオフの例を次に示します。

<p:calendar id="startDate" binding="#{startDateComponent}" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" />
<p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true">
    <f:validator validatorId="dateRangeValidator" />
    <f:attribute name="startDateComponent" value="#{startDateComponent}" />
</p:calendar>

(binding属性に注意してください。指定された変数名で正確に EL スコープでコンポーネントを使用できるようにします。また、この例は現状のままであり、絶対に Bean プロパティにバインドしないでください!)

dateRangeValidatorこのように見える場所:

@FacesValidator("dateRangeValidator")
public class DateRangeValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (value == null) {
            return; // Let required="true" handle.
        }

        UIInput startDateComponent = (UIInput) component.getAttributes().get("startDateComponent");

        if (!startDateComponent.isValid()) {
            return; // Already invalidated. Don't care about it then.
        }

        Date startDate = (Date) startDateComponent.getValue();

        if (startDate == null) {
            return; // Let required="true" handle.
        }

        Date endDate = (Date) value;

        if (startDate.after(endDate)) {
            startDateComponent.setValid(false);
            throw new ValidatorException(new FacesMessage(
                FacesMessage.SEVERITY_ERROR, "Start date may not be after end date.", null));
        }
    }

}

JSF ユーティリティ ライブラリ OmniFacesを使用している場合は、その<o:validateOrder>コンポーネントをそのまま使用することもできます。この要件は、カスタム バリデータを必要とせずに次のように達成できます。

<p:calendar id="startDate" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" />
<p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true" />
<o:validateOrder components="startDate endDate" />

以下も参照してください。

于 2013-09-30T13:13:16.937 に答える
6

最小および最大の日付を制限できる PrimeFaces を使用している場合。ユーザーはより大きな範囲を選択できませんでした。これは次の例です。

<p:calendar id="startDate" value="#{bean.startDate}" maxdate="#{bean.endDate}">
     <p:ajax event="dateSelect" update="endDate"/>
</p:calendar>
<p:calendar id="endDate" value="#{bean.endDate}" mindate="#{bean.startDate}" disabled="#{empty bean.startDate}">
      <p:ajax event="dateSelect" update="startDate"/>
 </p:calendar>
于 2015-11-12T19:48:37.973 に答える