Voila un sujet qui m'a bien pris la tête quand j'en ai eu besoin. Voici un post qui va vous permettre d'utiliser une simple requête AJAX sous Symfony2 (ou autre avec un peu d'imagination) grâce à la librairie JQuery.
Tout d'abord vous devez faire appel à la librairie JQuery, dans votre template principal (Le template principale se trouve généralement dans /App/Resources/Views/). Vous placez la ligne qui fera appel à la librairie, entre <head> et </head> :
En suite vous préparez le formulaire qui vas nous servir pour notre exemple, dans notre cas nous voulons remplir une liste déroulante vide par défaut grâce au choix fait sur une autre liste déroulante. Nous allons donc déclarer deux liste déroulante, la première qui contiendra une liste de choix à faire, ici une liste de pays, et une seconde liste déroulante vide, qu'on remplira avec une liste de ville selon le pays choisi dans la première liste déroulante :
Dans votre controller, créez un formulaire (cela fonctionne aussi avec les formulaire externalisé) :
Pour la seconde liste déroulante, ne pas oublier de lui préciser que la liste doit être vide grâce à "
Dans notre controller, nous déclarons donc cette fonction (Ne pas oublier Action à le fin du nom de la fonction) :
Voila pour le controller, maintenant allons dans notre page html (ou se trouvera le formulaire) pour lui indiquer de faire cette requête au moment ou nous avons faire notre choix de pays. Nous allons donc rajouter un petit morceau de code qui va se charger de détecter le changement de choix de notre liste pays, de récupérer ce choix et de faire appel à notre requête en lui donnant les informations nécessaire pour remplir notre liste de villes. Voici ce morceau de code avec les explications nécessaire :
Il n'y a plus rien à ajouter, si vous avez des soucis, n'hésitez pas à laisser des commentaires afin que je puisse y répondre ou améliorer ce petit tuto. J’espère que cela vous auras aidé.
Tout d'abord vous devez faire appel à la librairie JQuery, dans votre template principal (Le template principale se trouve généralement dans /App/Resources/Views/). Vous placez la ligne qui fera appel à la librairie, entre <head> et </head> :
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script>
En suite vous préparez le formulaire qui vas nous servir pour notre exemple, dans notre cas nous voulons remplir une liste déroulante vide par défaut grâce au choix fait sur une autre liste déroulante. Nous allons donc déclarer deux liste déroulante, la première qui contiendra une liste de choix à faire, ici une liste de pays, et une seconde liste déroulante vide, qu'on remplira avec une liste de ville selon le pays choisi dans la première liste déroulante :
Dans votre controller, créez un formulaire (cela fonctionne aussi avec les formulaire externalisé) :
$form = $this->createFormBuilder()
->add('pays', 'choice', array('choices' => array('fr' => 'France', 'ma' => 'Maroc' , 'es' => 'Espagne', 'uk' => 'Royaume Unis'), 'label' => 'Pays : '))
->add('ville', 'choice', array('empty_value' => '', 'required' => false, 'label' => 'Ville : '))
->getForm();
Pour la seconde liste déroulante, ne pas oublier de lui préciser que la liste doit être vide grâce à "
'empty_value' => ''".
Toujours dans le controller, nous allons créer la fonction qui va faire notre requête et remplir la liste déroulante avec la liste des ville du pays que nous avons sélectionné. Cette fonction va se comporter exactement comme les autres fonctions que l'on trouve dans notre controller, nous devons donc déclarer un chemin pour y accéder dans notre fichier routing.yml comme ceci :
IsMektebPostBundle_ajaxrq:
pattern: /ajaxrq
defaults: { _controller:IsMektebPostBundle:Controller:ajaxrq}
Dans notre controller, nous déclarons donc cette fonction (Ne pas oublier Action à le fin du nom de la fonction) :
public function ajaxrqAction() {
//Déclarer un tableau de type Array
$list_ville = array();
$request = $this->container->get('request');
//vérifier le type de la requête
if ($this->container->get('request')->isXmlHttpRequest()) {
//Récuperer le choix que vous fait dans la liste déroulante "Pays : "
$id = $request->request->get('id');
//Faire la requête pour récurer la liste des ville du pays sélectionné, grâce à leur "id" (fr, ma, es..), insérer ce résultat dans $villes
//Remplir la liste déroulante avec le résultat
foreach ($villes as $v) {
$list_ville[$v->getId()] = $v->getNomVille();
}
}
//Instancier une "réponse" grâce à l'objet "Response"
$response = new Response(json_encode($list_ville));
//Lui indiquer le type de format dans le quelle est envoyé la reponse
$response->headers->set('Content-Type', 'application/json');
//Retourner la tout à notre liste déroulante
return $response;
}
Voila pour le controller, maintenant allons dans notre page html (ou se trouvera le formulaire) pour lui indiquer de faire cette requête au moment ou nous avons faire notre choix de pays. Nous allons donc rajouter un petit morceau de code qui va se charger de détecter le changement de choix de notre liste pays, de récupérer ce choix et de faire appel à notre requête en lui donnant les informations nécessaire pour remplir notre liste de villes. Voici ce morceau de code avec les explications nécessaire :
<script>
//#form_pays représente la liste déroulante des pays, on lui indique de lancer une fonction au changement de choix dans la liste déroulante grâce à ".change(...).
$("#form_pays").change(function() {
$.ajax({
//On lui indique le type d'envoie des informations
type: 'POST',
//On lui indique le chemin de la fonction
url: '{{ path('IsMektebPostBundle_ajaxrq') }}',
//On lui donne la valeur du choix qu'on a fait, et id est la variable qui va contenir notre valeur, nous la retrouvons dans notre controller
data: 'id=' + $(this).val(),
//Enfin nous lui disons de remplir notre formulaire avec le resultat
success: function(response)
{
$('#form_ville').find("option").remove();
$.each(response, function(i, item) {
$('#form_ville').append(new Option(item, i));
});
}
}
)});
</script>
Il n'y a plus rien à ajouter, si vous avez des soucis, n'hésitez pas à laisser des commentaires afin que je puisse y répondre ou améliorer ce petit tuto. J’espère que cela vous auras aidé.