Как заставить валидацию зависеть от нажатой кнопки?

Я создал форму, и я хочу показать предыдущие существующие элементы таблицы, в то время как новый создает. Я хочу показать совпадающие элементы по мере заполнения формы. Но когда я пытаюсь отфильтровать список без заполнения формы, появляются сообщения о проверке, и таблица не обновляется.

Не знаю, возможно ли это, но что я не сделал бы что-то вроде этого:

<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, и это мой первый вопрос. Надеюсь, это полезно для многих людей и для меня.

Ответ 1

Я понимаю, что вы хотите фильтровать на основе поля ввода name. <p:commandButton> отправляет по умолчанию запрос ajax и имеет атрибут process, в котором вы можете указать, какие компоненты вы хотите обработать во время отправки. В вашем конкретном случае вы должны обработать только поле ввода name и текущую кнопку (чтобы ее действие было вызвано).

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

Атрибут process может принимать разделенный пробелом набор (относительных) идентификаторов клиентов компонентов, где @this относится к текущему компоненту. Он по умолчанию используется в случае <p:commandButton> - @form (который охватывает все поля ввода текущей формы и нажатой кнопки), поэтому все они были проверены в вашей первоначальной попытке. В приведенном выше примере все другие поля ввода не будут обрабатываться (и, следовательно, также не проверены).

Если вы, однако, намереваетесь пропустить проверку required для всех полей всякий раз, когда нажата данная кнопка, чтобы вы могли обработать несколько полей, которые необязательно должны быть заполнены, тогда вам нужно сделайте вместо этого 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" при нажатии другой кнопки. Трюк в приведенном выше примере состоит в том, что имя нажатой кнопки (которая по существу является идентификатором клиента) отправляется как параметр запроса и что вы можете просто проверить его присутствие на карте параметров запроса.

См. также:

Ответ 2

Я тестировал это с помощью non-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.

Ответ 3

В дополнение к ответу BalusC (очень полезный и полный), я хочу добавить, что при использовании <h:commandButton /> он будет проверять (обязательные, выборочные проверки) все поля в <h:form />, где расположена кнопка команды, поэтому, когда вам нужно использовать более одной командной кнопки, вы можете подумать о том, что использовать разные <h:form /> для разных обязанностей, чтобы избежать неожиданного поведения при отправке действий с помощью кнопок команд. Это хорошо объяснено в ответе BalusC: Несколько h: форма на странице JSF

Если ваша форма имеет валидации и вы не обновляете <h:form /> или вы не показываете сообщения, вы можете получить головную боль, думая, что <h:commandButton /> не запускает ваше действие, но, скорее всего, это проблема проверки,.

Ответ 4

Измените свою командную кнопку фильтра так, чтобы игнорировать проверку:

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

ИЗМЕНИТЬ:

Связанный пост на SO, я думаю, это также решит вашу проблему.

JSF 2.0: как пропустить проверку JSR-303 bean?