2010-05-11 7 views
2

J'ai un formulaire IceFaces et plusieurs champs de saisie.Pourquoi les validateurs de composants inchangés sont-ils appelés?

Disons que j'ai ceci:

<ice:selectOneMenu id="accountMenu" 
    value="#{accountController.account.aId}" 
    validator="#{accountController.validateAccount}"> 
    <f:selectItems id="accountItems" 
      value="#{accountController.accountItems}" /> 
</ice:selectOneMenu> 

et ceci:

<ice:selectOneMenu id="costumerMenu" 
    value="#{customerController.customer.cId}" 
    validator="#{customerController.validateCustomer"> 
    <f:selectItems id="customerItems" 
      value="#{customerController.customerItems}" /> 
</ice:selectOneMenu> 

Si je change d'une valeur, le validateur respectif est appelé, ce qui est bien. Mais aussi l'autre validateur est appelé, ce qui n'est pas bien, parce que l'utilisateur reçoit un message irritant pour insérer une valeur dans un champ auquel il allait peut-être faire attention. C'est comme piquer l'utilisateur avec un bâton pour "Dépêchez-vous maintenant!". MAL!

Je pensais que l'attribut "partialSubmit" contrôlait ce comportement, donc seulement la partie DOM soumise, qui est affectée par l'interaction de l'utilisateur, mais si je déclare les deux composants à soumettre partiellement, rien ne change. Les deux validateurs sont toujours appelés si la valeur d'un composant est modifiée.

Comment puis-je empêcher la validation de la totalité du formulaire jusqu'à ce qu'il soit complètement soumis?

+0

Quelle version d'ICEfaces utilisez-vous? –

+0

C'est IceFaces version 1.8.2 – bl4ckb0l7

Répondre

5

Lorsqu'un soumettront des partielle est exécutée, le cycle de vie complet JSF est toujours exécuté . Ainsi, la phase de validation est toujours traitée et tous les composants de la hiérarchie des composants sont validés.

Il y a de bonnes raisons à cela. Une modification d'un composant peut provoquer un changement (potentiellement invalide) dans un autre composant. Par exemple, une sélection d'un selectOneMenu peut définir une valeur dans un inputText. ICEfaces modifie le traitement d'une manière significative: Lors d'une soumission partielle, ICEfaces marque temporairement tous les composants autres que celui qui a déclenché le sumbit en tant qu'optionnel (required="false"). Ainsi, les validations "requises" sont ignorées. Cependant, ICEfaces ne désactive pas les autres validations.

Il existe deux solutions possibles à ce problème:

  1. Set immediate="true" en plus partialSubmit. Cela modifie légèrement le cycle de vie du composant lorsque l'envoi partiel est exécuté pour effectuer la validation dans la phase d'application des valeurs de demande. Cela peut entraîner l'annulation des autres validations.

  2. Détectez si une soumission partielle s'est produite dans votre validateur personnalisé. Ignore la validation si ce n'est pas le composant qui a déclenché l'envoi partiel. Malheureusement, il n'y a pas de documentation sur la façon de détecter une soumission partielle, mais j'ai trouvé la solution dans le code source de la classe com.icesoft.faces.application.PartialSubmitPhaseListener.

    Il se avère que ICEfaces ajoute deux paramètres de la requête lorsqu'une soumettre partielle est exécutée:

    • ice.submit.partial - à « true » pour indiquer que cela a été fait soumettre une partie.
    • ice.event.captured - contient l'ID du composant qui a généré l'envoi partiel.

Vous pouvez profiter de ces deux paramètres dans vos méthodes de validation. Voici un exemple:

public void validateAccount(FacesContext context, 
    UIComponent component, Object value) 
{ 
    if(!partiallySubmitted(context) || 
    componentWasPartiallySubmitted(context, component) 
    // Perform validation 
    } 

} 

public boolean partiallySubmitted(FacesContext context) { 
    ExternalContext externalContext = context.getExternalContext(); 
    Map parameterMap = externalContext.getRequestParameterMap(); 

    return "true".equals(parameterMap.get("ice.submit.partial")); 
} 

public boolean componentWasPartiallySubmitted(FacesContext context, 
    UIComponent component) { 
    ExternalContext externalContext = context.getExternalContext(); 
    Map parameterMap = externalContext.getRequestParameterMap(); 

    String componentId = (String) parameterMap.get("ice.event.captured"); 

    return component.getClientId(context).equals(componentId); 
} 

Bien sûr, l'accès direct aux deux paramètres de la requête est probablement non pris en charge. Cependant, jusqu'à ce que l'équipe ICEfaces fournisse un moyen de "détecter" un envoi partiel, il peut s'agir de votre seule option.

+0

Par curiosité, laquelle des deux options a fonctionné pour vous? immédiat = vrai, ou détectant la soumission partielle dans les validateurs? –

+0

Rien de tout cela, j'ai fait une refonte de mon application à ce stade, mais votre réponse m'a aidé à mieux comprendre le processus interne de gestion des requêtes. – bl4ckb0l7

+0

La deuxième option a fonctionné pour moi. – agrawalankur

0

Essayez d'effectuer la validation ajax sur l'événement onblur (ne savent pas comment le faire avec ICEfaces, mais avec richfaces il est tout simplement un <a4j:support event="onblur" />)