web-dev-qa-db-fra.com

Comment laisser la validation dépendre du bouton pressé?

J'ai créé un formulaire et je souhaite afficher les éléments existants précédents sur une table pendant la création d'un nouveau. Je souhaite afficher les éléments correspondants lorsque le formulaire se remplit. Mais lorsque j'essaie de filtrer la liste sans avoir rempli le formulaire, les messages de validation apparaissent et le tableau n'est pas mis à jour.

Je ne sais pas si c'est possible, mais ce que je veux faire quelque chose comme ça:

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

Je suis très nouveau à JSF.

34
Roteke

Je comprends que vous souhaitez filtrer en fonction du champ de saisie name. Le <p:commandButton> envoie par défaut une requête ajax et possède un attribut process dans lequel vous pouvez spécifier les composants que vous souhaitez traiter lors de la soumission. Dans votre cas particulier, vous devez alors traiter uniquement le champ de saisie name et le bouton courant (afin que son action soit invoquée) .

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

L'attribut process peut prendre une collection séparée par des espaces des ID client (relatifs) des composants, dans laquelle @this fait référence au composant actuel. Il est par défaut en cas de <p:commandButton> à @form (qui couvre tous les champs de saisie du formulaire actuel et du bouton pressé), c'est pourquoi ils ont tous été validés lors de votre première tentative. Dans l'exemple ci-dessus, tous les autres champs de saisie ne seront pas traités (et donc non validés).

Si vous avez cependant l'intention d'ignorer les champs required pour tous chaque fois que le bouton en question est enfoncé, afin que vous puissiez éventuellement traiter plusieurs champs qui n'ont pas nécessairement besoin de être tout rempli, alors vous devez faire le required="true" un conditionnel qui vérifie si le bouton a été enfoncé ou non. Par exemple, laissez-le évaluer true uniquement lorsque le bouton Enregistrer a été enfoncé:

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

De cette façon, il ne sera pas validé comme required="true" lorsqu'un autre bouton est enfoncé. L'astuce dans l'exemple ci-dessus est que le nom du bouton enfoncé (qui est essentiellement l'ID client) est envoyé en tant que paramètre de demande et que vous pouvez simplement vérifier sa présence dans la carte des paramètres de demande.

Voir également:

61
BalusC

J'ai testé cela avec des soumissions 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" />

La première entrée est requise et validée uniquement lors de la soumission du bouton Enregistrer1.

6
mnesarco

En plus de la réponse BalusC (très utile et complète), je veux ajouter que lorsque vous utilisez un <h:commandButton /> il validera (requis, validations personnalisées) tous les champs du <h:form /> où se trouve le bouton de commande, par conséquent, lorsque vous devez utiliser plusieurs boutons de commande, vous pouvez considérer qu'il est recommandé d'utiliser différents <h:form /> à différentes responsabilités pour éviter un comportement inattendu lors de la soumission des actions des boutons de commande. Il est bien expliqué dans une réponse BalusC: Multiple h: formulaire dans une page JSF

Si votre formulaire comporte des validations et que vous ne mettez pas à jour le <h:form /> ou si vous n'affichez pas de messages, vous pourriez avoir mal à la tête en pensant que le <h:commandButton /> ne déclenche pas votre action, mais il s'agit probablement d'un problème de validation qui n'a pas été affiché.

6
Cristian Arteaga

Modifiez votre bouton de commande de filtre comme ceci pour ignorer la validation:

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

ÉDITER:

Le poste connexe sur SO, je pense que cela résoudra également votre problème

JSF 2.0: Comment ignorer la validation du bean JSR-303?

2
mprabhat