L’autocomplétion avec sfWidgetFormJQueryAutocompleter

Après avoir eu quelques difficultés à mettre en place l’auto-complétion sur mes champs text dans Symfony avec le sfWidgetFormJQueryAutocomplete (du plugin sfFormExtraPlugin), je me suis dis que ça pourrait utile de faire un petit howto. Bien sûr je part du principe que vous avez déjà installé le plugin sfFormExtraPlugin (N’oubliez pas de vider le cache après l’installation).

Bien, rentrons directement dans le vif du sujet, il y a quatre fichiers à modifier :

1) La classe du formulaire :

  public function configure()
  {
    sfProjectConfiguration::getActive()->loadHelpers('Url');   
    $this->widgetSchema['mon_champ'] = new sfWidgetFormJQueryAutocompleter(array(
       'url'    => url_for('@autocomplete_test'),
       'config' => '{scrollHeight: 200, minChars: 1, delay: 500}'
    ));
  }

Je ne connais pas encore tous les paramètres que l’on peut mettre dans la partie ‘config’. Pour le moment j’en connais quatre qui sont assez explicites par leurs noms : scrollHeight, minChars, autoFill (false par défaut) et delay. Ce dernier paramètre est d’ailleurs très utile car il permet d’imposer un délai avant l’envoi de la requête $_GET au serveur afin d’éviter de le surcharger inutilement.

2) Le modèle (avec le suffixe Table)

  public function retrieveForSelect($q, $limit)
  {                
      $query = $this->createQuery('t')
        ->where('t.name LIKE ?', '%'.$q.'%')
        ->orderBy('t.name')
        ->limit($limit)
        ->execute();

      $response = array();
      foreach($query as $data)
      {
        $response[$data->getId()] = $data->getName();
      }

      return $response;
  }

Pour récupérer les données, il faut créer une fonction dans le modèle et pas le faire dans le contrôleur sinon on ne respecte pas le modèle MVC !

3) Le contrôleur (actions.php)

  public function executeAjax(sfWebRequest $request)
  {
    $this->getResponse()->setContentType('application/json');

    $data = Doctrine_Core::getTable('MaTable')->retrieveForSelect($request->getParameter('q'), $request->getParameter('limit'));

    return $this->renderText(json_encode($data));
  }

4) Le fichier routing.yml

autocomplete_test:
  url
:  /test/autocomplete
  param
: { module: test, action: ajax }

Voilà la mise en œuvre n’est pas si compliqué que ça finalement. Moi j’utilise Doctrine mais pour ceux qui utilisent Propel il y a un tuto disponible à cette adresse.

8 Commentaires sur “L’autocomplétion avec sfWidgetFormJQueryAutocompleter”

  • kikinus
    # Le 27 août 2012 à 13 h 19 min

    Bonjour,

    Je m’excuse, ma question va être sans doute bête car je suis débutant Symfony.

    $query = $this->createQuery(‘t’)
    ->where(‘t.name LIKE ?’, ‘%’.$q.’%')
    ->orderBy(‘t.name’)
    ->limit($limit)
    ->execute();

    $response = array();
    foreach($query as $data)
    {
    $response[$data->getId()] = $data->getName();

    A quoi fait référence name ? nom du champs autocompleté?

    Merci

    1
  • mika
    # Le 14 septembre 2012 à 20 h 15 min

    Bonjour,

    Sincèrement désolé pour le délai de réponse. Pour ceux qui se poserait la question :

    ‘name’ est le champ dans la bdd sur lequel on effectue la recherche.
    Et le ‘getName()’ est la méthode retournant la valeur de ce champ.

    Le but de cet exemple étant d’afficher une liste de noms avec une auto-complétion sur le nom.

    2
  • kate
    # Le 31 octobre 2012 à 9 h 55 min

    Merci beaucoup, ça marché du premier coup.
    Miatemant, je veux lier l’autocompletion sur 2 champs ville + cp.

    Cordialement

    3
  • mika
    # Le 5 novembre 2012 à 19 h 23 min

    @kate : Il suffit de modifier ta requête doctrine, tu as sûrement déjà du trouver.

    $query = $this->createQuery(‘t’)
    ->where(‘t.ville LIKE ?’, ‘%’.$q.’%')
    ->orWhere(‘t.cp LIKE ?’, ‘%’.$q.’%')
    ->orderBy(‘t.ville’)
    ->limit($limit)
    ->execute();

    $response = array();
    foreach($query as $data)
    {
    $response[$data->getId()] = $data->getVille().’ (‘.$data->getCp().’)';
    }

    return $response;

    Comme cela l’utilisateur peut effectuer une recherche sur la ville ET sur le code postal. De plus, dans la liste des suggestions on retourne la ville et son code postal entre parenthèses.

    4
  • Thierry
    # Le 25 avril 2013 à 9 h 39 min

    Bonjour,

    Merci pour le tuto, il est vraiment tres interessant.
    Je me permet une petite question.
    Dans le formulaire j’ai un champ Personne qui me permet d’effectuer l’autocomplete et aussi un champ cacher qui devrait recevoir l’ID de la personne. Je vois bien comment récupérer de la requete le nom de la personne et son Id mais comment afecter l’ID au champ caché ?
    Par avance merci de votre reponse

    5
  • mika
    # Le 25 avril 2013 à 20 h 34 min

    Bonjour,

    Pour chaque élément du tableau la clé doit correspondre à l’ID de la personne, comme dans l’exemple ci-dessous :

    foreach($query as $data) {
    $response[$data->getIdPersonne()] = $data->getNomPersonne();
    }

    Comme ça c’est bien l’ID de la personne qui est inséré dans le champ caché.

    6
  • Thierry
    # Le 29 avril 2013 à 7 h 54 min

    Tu as raison.

    Encore une petite question :
    Je viens d’installer symfony2, sfForm n’est plus compatible..
    Tu n’aurais pas un tuto aussi bien fait avec symfony2 ?

    7
  • mika
    # Le 6 mai 2013 à 20 h 38 min

    Hélas je n’ai pas encore eu l’occasion de me mettre à Symfony 2, je n’ai pas de tuto sous la main.

    Malgré tout si c’est simplement pour mettre en place un autocomplete (jQuery UI ou autre) tu dois pouvoir te passer facilement du sfForm. Dans le paramètre URL du plugin il suffit de mettre directement la route correspondante « autocomplete_test ». Le code modèle/contrôleur ne devrait pas trop changer.

    Bon courage !

    8

Laisser un commentaire

Vous pouvez ces balises HTML dans votre commentaire :
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current month ye@r day *