ti-enxame.com

Como deixar a validação depender do botão pressionado?

Eu criei o formulário e quero mostrar os itens existentes anteriores em uma tabela enquanto um novo está sendo criado. Gostaria de mostrar itens correspondentes à medida que o formulário está sendo preenchido. Mas quando tento filtrar a lista sem ter o formulário preenchido, as mensagens de validação aparecem e a tabela não é atualizada.

Não sei se é possível, mas o que eu quero fazer algo assim:

<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>

Eu sou muito novo no JSF.

34
Roteke

Entendo que você deseja filtrar com base no campo de entrada name. O <p:commandButton> envia por padrão uma solicitação ajax e possui um atributo process no qual é possível especificar quais componentes você gostaria de processar durante o envio. No seu caso particular, você deve processar apenas o campo de entrada name e o botão atual (para que sua ação seja invocada) .

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

O atributo process pode ter uma coleção separada por espaço de IDs de cliente (relativos) dos componentes, em que @this refere-se ao componente atual. O padrão é no caso de <p:commandButton> para @form (que abrange todos os campos de entrada do formulário atual e o botão pressionado), é por isso que todos foram validados na sua tentativa inicial. No exemplo acima, todos os outros campos de entrada não serão processados ​​(e, portanto, também não serão validados).

Se você, no entanto, pretende pular a validação required para os campos todos sempre que o botão em questão for pressionado, para que você possa eventualmente processar vários campos que não necessariamente precisam ser tudo preenchido, então você precisa fazer o required="true" uma condição que verifica se o botão foi pressionado ou não. Por exemplo, avalie true somente quando o botão Salvar foi pressionado:

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

Dessa forma, não será validado como required="true" quando um botão diferente é pressionado. O truque no exemplo acima é que o nome do botão pressionado (que é essencialmente o ID do cliente) foi enviado como parâmetro de solicitação e você pode apenas verificar sua presença no mapa de parâmetros de solicitação.

Veja também:

61
BalusC

Eu testei isso com envios que não são do 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" />

A primeira entrada é necessária, validada apenas no envio do botão Salvar1.

6
mnesarco

Além da resposta do BalusC (muito útil e completa), quero acrescentar que quando você usa um <h:commandButton /> validará (exigido, validações personalizadas) todos os campos no <h:form /> onde o botão de comando está localizado, portanto, quando você precisar usar mais de um botão de comando, poderá considerar que é uma boa prática usar diferentes <h:form /> para responsabilidades diferentes para evitar comportamentos inesperados nas ações de envio dos botões de comando. Está bem explicado em uma resposta do BalusC: Formulário h múltiplo em uma página JSF

Se o seu formulário tiver validações e você não atualizar o <h:form /> ou você não mostra mensagens, pode sentir dor de cabeça pensando que o <h:commandButton /> não está disparando sua ação, mas provavelmente é um problema de validação que não foi mostrado.

6
Cristian Arteaga

Mude o botão de comando do filtro como este para ignorar a validação:

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

EDITAR:

A postagem relacionada no SO, acho que isso também resolverá seu problema

JSF 2.0: Como ignorar a validação de bean JSR-303?

2
mprabhat