web-dev-qa-db-ja.com

押されたボタンに応じて検証を行う方法は?

フォームを作成しましたが、新しいアイテムの作成中に、テーブルに以前の既存のアイテムを表示したいと思います。フォームがいっぱいになったときに一致するアイテムを表示したいと思います。しかし、フォームを完成させずにリストをフィルタリングしようとすると、検証メッセージが表示され、テーブルが更新されません。

それが可能かどうかわからないが、私はこのようなことをしたい:

<h:form id="form">

    <h:outputText value="Name: "/>
    <p:inputText value="#{itemsBean.name}" id="name" required="true"/>
    <br/>
    <h:outputText value="Description: "/>
    <p:inputText value="#{itemsBean.description}" id="description" required="true"/>

    <p:commandButton value="Save" update="form" actionListener="#{itemsBean.save}"/> //validate and save
    <p:commandButton value="Filter" update="form" actionListener="#{itemsBean.updateItemsList}"/> //don't validate, and update the table.

    <p:dataTable id="list" value="#{itemsBean.itemsList}" var="item">     
        <p:column>
            <h:outputText value="#{item.name}"/>
        </p:column>
        <p:column>
            <h:outputText value="#{item.description}"/>
        </p:column>
    </p:dataTable>

</h:form>

私はJSFが初めてです。

34
Roteke

name入力フィールドに基づいてフィルタリングすることを理解しています。 <p:commandButton>はデフォルトでajaxリクエストを送信し、サブミット中に処理するコンポーネントを指定できるprocess属性を持っています。特定のケースでは、name入力フィールドと現在のボタンを処理するonly(そのアクションが呼び出されるようにする) 。

<p:commandButton process="@this name" ... />

process属性は、コンポーネントの(相対)クライアントIDのスペース区切りのコレクションを取ることができます。@thisは現在のコンポーネントを指します。 <p:commandButton>から@form(現在のフォームのすべての入力フィールドと押されたボタンを含む)の場合はデフォルトであるため、最初の試行ですべて検証されました。上記の例では、他のすべての入力フィールドは処理されません(したがって検証もされません)。

ただし、問題のボタンが押されるたびにallフィールドのrequired検証をスキップする場合は、最終的に複数のフィールドを処理できます。必ずallを入力する必要があり、ボタンが押されたかどうかを確認する代わりにrequired="true"を条件付きにする必要があります。たとえば、保存ボタンが押されたときにのみtrueを評価させます:

<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" value="Save" ... />

この方法では、別のボタンが押されたときにrequired="true"として検証されません。上記の例の秘trickは、押されたボタンの名前(本質的にはクライアントID)が要求パラメーターとして送信され、要求パラメーターマップでその存在を確認できることです。

こちらもご覧ください:

61
BalusC

私はこれを非ajaxサブミットでテストしました:

<p:inputText ... required="#{not empty param.includeInSave1}" />
...
<p:inputText ... required="true" />
...
<p:commandButton value="Save1" ajax="false">
  <f:param name="includeInSave1" value="true" />
</p:commandButton>

<p:commandButton value="Save2" ajax="false" />

最初の入力は、Save1ボタンの送信時にのみ検証される必要があります。

6
mnesarco

さらに、BalusCの回答(非常に便利で完全な)に加えて、<h:commandButton />を使用すると、コマンドボタンが配置されている<h:form />のすべてのフィールドを検証します(必須、カスタム検証)。したがって、複数のコマンドボタンを使用する必要がある場合、コマンドボタンの送信アクションでの予期しない動作を回避するために、異なる<h:form />を異なる責任で使用することをお勧めします。 BalusCの回答でよく説明されています: JSFページの複数のh:form

フォームに検証があり、<h:form />を更新しない場合、またはメッセージを表示しない場合、<h:commandButton />がアクションを起動していないが、おそらく検証の問題であると考えて頭痛がする可能性があります表示されていません。

6

検証を無視するには、次のようにフィルターコマンドボタンを変更します。

<p:commandButton value="Filter" update="list" actionListener="#{itemsBean.updateItemsList}" process="@this"/>

編集:

SOに関する関連記事、これはあなたの問題も解決すると思います

JSF 2.0:JSR-303 Bean検証をスキップする方法?

2
mprabhat