Avec JSF il est simple d'ajaxifier un composant : il suffit d'inclure la balise <f:ajax> dans la balise du composant (voir section "Ajax" à la fin du support de cours sur JSF).
Par exemple, si vous mettez la balise <f:ajax>
à l'intérieur de la balise <f:inputText>
qui permet de saisir l'identificateur du compte source, quand l'utilisateur tape l'identificateur et sort du champ de saisie de cet identificateur, une requête Ajax part vers le serveur.
La requête est la même que celle qui aurait été envoyée par la soumission du formulaire mais, par défaut, cette requête ne tient compte que de l'identificateur du compte source et ne modifie rien dans la page quand la réponse est retournée par le serveur HTTP. Des attributs de <f:ajax>
permettent de changer le comportement par défaut ; en particulier avec l'attribut render
on peut indiquer les champs à mettre à jour au retour de la requête.
Voici le comportement qu'on souhaite pour la requête Ajax : le serveur recherche dans la base de données un compte qui a l'id tapé par l'utilisateur. Quand la requête revient sur le client HTTP, les champs de la page qui ont été indiqués dans l'attribut render de <f:ajax>
sont mis à jour. Si un champ a été ajouté au formulaire juste à côté de l'id, pour contenir le nom du propriétaire du compte et si ce champ est indiqué dans l'attribut render
, le nom du propriétaire du compte est alors affiché à côté de l'id. Si aucun compte n'a cet id il faut afficher un message d'erreur. Le composant <f:ajax>
a donc un attribut render
qui désigne le nom du propriétaire et le message d'erreur (pour couvrir les 2 cas).
Le traitement est le même pour l'identificateur du compte destination.
Il reste à faire exécuter la recherche d'un compte avec un certain id, avec la requête Ajax.
2 solutions (vous en trouverez peut-être d'autres) :
<h:inputText>
qui charge un compte à partir de de l'id saisi. La validation échoue si l'id ne correspond à aucun compte. Le validateur peut être donné de multiples façons. Vous pouvez utiliser par exemple l'attribut validator
de <h:inputText>
en donnant comme valeur une méthode d'un backing bean (comme le convertisseur du TP 1). Quand la requête Ajax est lancée sur, par exemple, l'id source, cet id est traité par le cycle de vie JSF et donc son validateur est exécuté. Ce validateur récupère le compte avec l'id saisi (erreur si pas de compte avec cet id) et le met dans une variable d'instance du backing bean, qui servira au moment d'effectuer le transfert.void
et paramètres de type FacesContext
, UIComponent
et Object
(la valeur à valider). ValidatorException
en lui passant une instance de FacesMessage
. <f:ajax>
pour charger un compte à partir de l'id saisi dans le <h:inputText>
. Le compte est mis dans une variable d'instance du backing bean comme pour la 1ère solution. La correction de ce TP utilise la 1ère solution qui pose moins de problème (voir ci-dessous) et qui correspond plus à l'esprit de JSF.
Remarque : Vous aurez peut-être des messages d'erreur ou des avertissements (dans les logs du serveur d'application) liés aux cookies utilisés par la mémoire Flash si l'utilisateur tape la touche "Entrée" après avoir tapé les identificateurs. C'est une erreur de l'utilisateur car, selon les normes HTML, la touche Entrée soumet le formulaire ; il faut passer aux autres champs par la touche Tab ou en utilisant la souris. Vous pouvez ignorer ces messages. Pour la 2ème solution ce problème empêchera des messages d'erreur de s'afficher mais rien de grave.