Listes déroulantes mises à jours en Ajax avec jQuery

Un petit TIPS pour faire des listes déroulantes liées qui s’enrichissent en fonction de la valeur choisie sur l’une d’entre elles.
(J’ai l’impression que la phrase est très compliqué pour pas grand chose ^^)
Le tout en Ajax en utilisant jQuery.

Dans mon exemple, ça sera tout simplement un formulaire Lambda avec des listes déroulante pour les Régions et les Départements.
Le fonctionnement est le suivant. Par défaut les listes déroulantes sont initialisées avec toutes les valeurs. Dés que l’on choisi une valeur pour la région, la liste déroulante des département affine sa liste pour ne proposer que les départements de la région saisie.

Vite fait, le schéma utilisé :

...
Region:
  tableName:  region
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:       { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:      { type: string(255), notnull: true }
 
Departement:
  tableName: departement
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:        { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:       { type: string(255), notnull: true }
    region_id: { type: integer(4), unsigned: true }
  relations:
    Region:
      local:        region_id
      foreign:      id
      foreignAlias: Departements
      onDelete:     CASCADE
...

Juste pour mettre en évidence la relation entre le Département et la Région, avec le très important le foreignAlias que j’aime tant 😀

Pour faire fonctionner tout ça on va avoir besoin de :
– 1 route
– 1 action minuscule
– 1 partial de 4 lignes
– 1 tout petit bout de javascript

La route :

?View Code JAVASCRIPT
# routing.yml
...
ajax_departement:
  url:   /ajax/departement
  param: { module: lambda, action: ajaxDepartement }
...

L’action :

// actions.class.php
 
  /**
   * requete ajax pour avoir la liste des déparements de la région
   *
   * @param sfWebRequest $request
   */
  public function executeAjaxDepartement(sfWebRequest $request)
  {
    $region = Doctrine::getTable('Region')->findOneById($request->getParameter('region'));
    return $this->renderPartial('lambda/selectDepartement', array('region' => $region));
  }

Le partial :

// _selectDepartement.php
<option value=""></option>
<?php foreach($region->getDepartements() as $departement): ?>
<option value="<?php echo $departement->getId() ?>"><?php echo $departement->getNom() ?></option>
<?php endforeach; ?>

Et enfin le petit bout de code jQuery à rajouter au formulaire :

?View Code JAVASCRIPT
<script language="javascript">
$(document).ready(function(){
  $("#mon_formulaire_lambda_region_id").change( function() {
    $.post("/ajax/departement", { region: $(this).val() },
    function(data){
      $("#mon_formulaire_lambda_departement_id").html(data);
    });
  });
});
</script>

Pour le javascript plusieurs solutions. Soit l’inclure directement dans la vue avec les balises comme je l’ai fait ici.
Soit faire un fichier .js que l’on met dans /web/js/mon_fichier.js (bien mais pas top :P).

Le plus « propre » est de faire une vue et d’utiliser le sf_format et d’inclure le fichier via une route.
On verra ça lors d’un prochain post 😉

@bientôt !

NB : Bien entendu il faut que jQuery soi inclus :
– Soit il est inclus dans le view.yml
– Soit directement dans la vue avec un use_javascript(‘jQuery.js’)

Partagez cet article