38 votes

JSF2.0 ne prend pas en charge la validation entre champs, existe-t-il une solution de contournement?

JSF2.0 vous permet uniquement de valider la saisie sur un champ, comme vérifier pour voir si c'est une certaine longueur. Il ne vous permet pas d'avoir un formulaire qui dit, "entrez la ville et l'état, ou entrez juste un code postal."

Comment avez-vous pu contourner cela? Je ne suis intéressé que par les réponses qui impliquent la phase de validation de JSF. Je ne souhaite pas mettre de logique de validation dans les beans gérés.

62voto

BalusC Points 498232

La meilleure approche personnalisée que j'ai vu et utilisé comme mesure consiste à créer un <h:inputHidden> domaine <f:validator> où la référence de tous les composants impliqués en tant que <f:attribute>. Si vous déclarez avant d' être validé composants, vous pouvez obtenir les valeurs transmises à l'intérieur du programme de validation par UIInput#getSubmittedValue().

E. g.

<h:form>
    <h:inputHidden value="true">
        <f:validator validatorId="fooValidator" />
        <f:attribute name="input1" value="#{input1}" />
        <f:attribute name="input2" value="#{input2}" />
        <f:attribute name="input3" value="#{input3}" />
    </h:inputHidden>
    <h:inputText binding="#{input1}" value="#{bean.input1}" />
    <h:inputText binding="#{input2}" value="#{bean.input2}" />
    <h:inputText binding="#{input3}" value="#{bean.input3}" />
    <h:commandButton value="submit" action="#{bean.submit}" />
    <h:messages />
</h:form>

(veuillez noter que l' value="true" sur le caché d'entrée; la valeur réelle en fait n'a pas d'importance, mais gardez à l'esprit que le validateur ne sera pas nécessairement être déclenché quand il est null ou vide, en fonction de la JSF de version et de configuration)

avec

@FacesValidator(value="fooValidator")
public class FooValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        UIInput input1 = (UIInput) component.getAttributes().get("input1");
        UIInput input2 = (UIInput) component.getAttributes().get("input2");
        UIInput input3 = (UIInput) component.getAttributes().get("input3");
        // ...

        Object value1 = input1.getSubmittedValue();
        Object value2 = input2.getSubmittedValue();
        Object value3 = input3.getSubmittedValue();
        // ...
    }

}

Si vous déclarez l' <h:inputHidden> après être validé composants, puis les valeurs des composants sont déjà convertis et validées, et vous devriez obtenir en UIInput#getValue() ou peut - UIInput#getLocalValue() (dans le cas d' UIInput n'est pas isValid()) à la place.

Voir aussi:

Alternativement, vous pouvez utiliser la 3ème partie tags/composants pour que. RichFaces , par exemple, a un <rich:graphValidator> balise pour cela, Seam3 a un <s:validateForm> pour cette, et OmniFaces a plusieurs <o:validateXxx> des composants pour ce qui sont tous présentés ici. OmniFaces utilise un composant de base de l'approche en vertu de laquelle le travail est fait en UIComponent#processValidators().

2voto

Jens Points 1073

Apache ExtVal n'a pas été mentionné ici.

Il y a quelques croix validations (entre autres validations qui pourrait être utile):

https://cwiki.apache.org/confluence/display/EXTVAL/Property+Validation+Usage#PropertyValidationUsage-CrossValidation

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X