Bonjour,

Je crée des composants JSF en JAVA, de manière à obtenir un champ de saisie, suivi d'un lien qui lance une recherche.

J'ai un HtmlInputText auquel j'ai lié un validateur perso qui vérifie que l'utilisateur a bien saisi une valeur numérique.
Sa valeur est "bindé" à une propriété de mon bean managé.

A côté j'ai un HtmlCommandLink, dont l'action fait référence à une méthode de mon bean managé.


Jusque là tout va bien ! L'action de mon lien, et la validation fonctionnent correctement. (accès à un autre écran affichant les résultats)


Le problème apparaît lorsque je veux intercepter la touche "entrer" pour ne pas valider mon formulaire, mais cliquer sur mon lien : je dois alors donner des IDs à mon formulaire et à mon lien, ce que JSF n'accepte pas comme ça !
En effet une exception est levée pour indiquer que l'ID est déjà utilisé lorsqu'on recharge la page...

J'ai lu qu'il suffisait de faire un setTransient(true) pour régler ce petit souci, ce que j'ai fait avec succès... ou presque

Car maintenant, si je rentre une mauvaise valeur (ex : "uneLettre"), au lancement de la recherche mon validateur va bien me jeter, et m'indiquer que ce n'est pas un numérique.
Si ensuite je relance une recherche (avec une valeur correcte ou non), rien ne se passe : la page est rechargée mais ni le validateur, ni la méthode associée à l'action ne sont appelés !!

Au niveau du cycle JSF, on passe directement de la phase 1 RESTORE_VIEW à la phase 6 RENDER_RESPONSE.


Par contre au coup suivant cela fonctionne à nouveau ! et ce jusqu'à ce qu'une erreur de validation soit levée : la recherche qui suivra sera sans effet


La création des composants :
INPUT
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
num = (HtmlInputText)context.getApplication().createComponent(HtmlInputText.COMPONENT_TYPE);
num.setRequired(true);
num.setRequiredMessage("Veuillez entrer un numéro.");
num.addValidator(new MonValidateur());
num.setOnkeypress("if (event.keyCode == 13) {document.getElementById('formToSearch:valid').click();return false;}");
ValueBinding vb =
            getFacesContext().getApplication().
            createValueBinding("#{monBean.value}");
		num.setValueBinding("value", vb);
LINK
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
link = (HtmlCommandLink)context.getApplication().createComponent(HtmlCommandLink.COMPONENT_TYPE);
link.setId("valid");
link.setActionExpression(context.getApplication().getExpressionFactory().createMethodExpression(context.getELContext(), "#{monBean.search}", null, new Class[0]));
 
//2 outcome, suivant le numero recherche, la page de resultat n est pas la meme
//Premier
GetRequestExpression getRequestExpression = new GetRequestExpression();
ValueExpression targetExpression = context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), "/pages/search/type1.jsf", Object.class);
getRequestExpression.addBaseUrl(targetExpression);
final Outcome outcome;
final String outcomeName = "type1";
 
//Second	    
outcome = new RedirectOutcome(getRequestExpression, true);
 
GetRequestExpression getRequestExpression2 = new GetRequestExpression();
ValueExpression targetExpression2 = context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), "/pages/search/type2.jsf", Object.class);
getRequestExpression2.addBaseUrl(targetExpression2);
final Outcome outcome2;
final String outcomeName2 = "type2";
 
outcome2 = new RedirectOutcome(getRequestExpression2, true);
Si quelqu'un peut m'aider à y voir clair...