2013-01-15 3 views
35

J'ai plusieurs formulaires, où j'ai des champs obligatoires et facultatifs.JSF saut Obligatoire-Validation sans immédiat = vrai

Pour soumettre une telle forme, j'ai besoin de la validation sur l'attribut requis pour être exécuté, qui fonctionne bien. Pour annuler une telle forme que j'utilise l'attribut immediate="true" sur le p:commandbutton, ce qui rend son action se produit au cours de la Appliquer demande Valeurs -Phase à l'adresse indiquée ici: How to skip validation when a specific button is clicked?

Cependant, pour les grandes formes que je veux fournir utilisateur avec un bouton de sauvegarde, afin qu'il puisse continuer plus tard.

Pour enregistrer simplement l'état actuel, je veux également ignorer la validation de l'attribut requis. Cependant, l'utilisation de immediate="true" ne fonctionne pas, car alors ma méthode de sauvegarde simple n'enregistre rien, car le cycle de vie JSF n'atteint jamais la phase "UpdateModelValues". (Selon http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html)

Alors, comment contourner la vérification requise sans sauter la moitié du cycle de vie?

+0

Étant donné la réponse, c'est techniquement dupe de [Comment laisser la validation dépendre du bouton enfoncé?] (Http://stackoverflow.com/q/8370675). – BalusC

+0

@BalusC Vous avez raison, mais l'autre question concerne un détail "technique" exact. Celui-ci, j'ai créé quand je n'étais pas si familier avec tous les JSF-Wordings (je l'ai corrigé un peu aujourd'hui) - et donc il correspond parfaitement à la recherche Google correspondante, un * débutant * pourrait soumettre: https: // www .google.de/webhp? sourceid = chrome-instant & ion = 1 & espv = 2 & ie = UTF-8 # q = jsf% 20skip% 20validation% 20without% 20immediate (Cependant, les deux sont classés haut) – dognose

Répondre

54

Chaque bouton crée une entrée dans la liste des paramètres tant qu'elle est membre du formulaire. Je simple, appliqué un chèque de la présence de cette entrée au paramètre « requis »:

<h:form id="form" prependId="true"> 
... 
<p:inputText id="someId" 
    required="#{param['form:save']==null}" ... /> 
... 
<p:commandButton id="save" value="Save" /> 
<p:commandButton id="submit" value="Submit" /> 
<p:commandButton id="cancel" value="Cancel" immediate="true" /> 
</h:form> 

Lorsque je clique sur « Soumettre » le param['form:save'] est NULL, qui tourne alors l'expression de true si la validation est exécutée .

Lorsque je clique sur "Enregistrer" le param['form:save'] est NOT NULL (mais vide!), Ce qui résout à false de sorte que la validation est ignorée. (Ou disons JSF pense que ce n'est pas un champ obligatoire en raison de l'expression beeing évalué à false)

+2

sur une note: 'true and' est évidemment pas nécessaire ici;) – dognose

+0

@BalusC J'utilise Primefaces. Pas sûr, s'il y a quelque chose d'égal. (Je ne l'ai pas trouvé maintenant) – dognose

+0

Great work! fantastique. Après 3 heures de folie j'ai trouvé ta réponse. Super cool! – 98percentmonkey

3

Ceci est une excellente question et une réponse très utile. Cette approche permet d'économiser beaucoup de tracas avec immediate="true".

Je voudrais ajouter cette information (mais je ne suis pas autorisé à commenter pour le moment). Vos exemples de code semblent exiger JSF 2.0 ou supérieur (corrigez-moi). Si vous êtes comme moi damnés à utiliser JSF 1.1/1.2 alors tenir compte de ces changements/ajouts:

<h:form id="form"> 
... 
<p:inputText id="someId" required="#{!empty param['save']}" ... /> 
... 
<p:commandButton id="save" value="Save" /> 
</h:form> 
  • Il n'y a pas d'attribut prependId dans JSF 1.1
  • Par conséquent, dans le param [...] vous devez spécifiez uniquement l'ID de bouton
  • Vous utilisez une syntaxe ="{true and ...}" qui peut être une erreur (non #)?
  • Comme vous pouvez le voir à partir de votre propre historique d'édition, la logique "null or not null" n'est pas très intuitive :) C'est pourquoi j'ai immédiatement aimé la version !empty ... quand je suis tombé dessus.
+0

'{true and ...}' manque le "#", c'est correct. aussi le vrai est obsolet. C'est "là", parce que nous générons toutes nos formes automatiquement (au moment de la conception), et avons la possibilité de définir, si quelque chose est nécessaire ou non. Ensuite, si un formulaire permet de "sauvegarder", nous avons simplement ajouté la vérification des paramètres. Et parce que vous avez raison - le null-thing n'est pas très intuitif, nous avons décidé de laisser la valeur "original" (vrai ou faux) avec cette vérification pour une meilleure lisibilité. – dognose

+0

JSF 1.1 ajoute par défaut l'ID client du formulaire. Donc, vous devriez toujours utiliser 'form: save'. Je ne suis pas sûr pourquoi dognose a déclaré explicitement 'prependId =" true "' car c'est la valeur par défaut déjà. – BalusC

+0

@BalusC J'ai essayé ça, mais ça ne marche pas pour moi. Si j'utilise 'required =" # {! Vide param ['save']} "', j'obtiens les erreurs de validation prévues lors de la publication d'un formulaire à moitié rempli. Si j'utilise 'required =" # {! Vide param ['form: save']} "' à la place, aucune validation ne se produit - et j'obtiens beaucoup d'erreurs de base de données;). – SebastianH

0

Dans mon cas, je ne trouve pas le clientId du bouton dans les params mais j'ai trouvé ce param['javax.faces.source'] = buttonClientId dans le requestmap. La valeur sera le clientId du bouton cliqué.

4

Si vous voulez ignorer la validation lorsque vous cliquez sur le bouton, ajoutez facilement le paramètre au bouton où vous voulez l'ignorer. Exemple:

<p:commandButton value="button1" action="#{bean.action()}" > 
    <f:param name="skipValidator" value="true"/> 
</p:commandButton> 

Puis, en validateur vous pouvez lire ce paramètre et s'il est vrai sauter alors il:

@FacesValidator("com.validators.MyValidator") 
public class MyValidator implements Validator{ 

    public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException { 
    if(!continueValidation()){ 
     return; 
    } 
    // validation process 
    } 

protected boolean continueValidation() { 
    String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator"); 
    if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) { 
     return false; 
    } 
    return true; 
    } 
} 
+0

Cette approche n'ignore pas les valeurs du modèle de mise à jour du cycle de vie standard, mais ignore la propriété FacesValidator. Utile pour le bouton "Clean". Tnks l'homme. – aspadacio

0

Une alternative à ce que d'autres ont proposé est d'utiliser une coutume BeanValidator qui validera la forme si c'est le cas, cliquez sur le bouton avec id enregistrer. Tout autre bouton non implicitement défini pour effectuer la validation ne validera pas mais simplement soumettre vos données disponibles. Trouver l'exemple complet et agréable here