Scriptaculous Ajax.Autocompleter : Mettre en place un champ de saisie avec suggestions dynamiques

28 octobre 2007Ajax, Autocompletion, Javascript, Scriptaculous
 Cet article a été rédigé il y a plusieurs années et peut ne plus être tout à fait à jour…

Vous avez tous déjà développé une application Web contenant un formulaire au sein duquel vous avez inséré une liste de choix, en utilisant la balise HTML <select>.

Mais une liste déroulante n'est réellement utilisable que si elle ne contient que peu d'entrées ; pas plus d'une trentaine, dirais-je, au grand maximum.
Et une liste <select> force l'utilisateur à choisir une des valeurs que vous lui proposez.

Dans certains cas, vous pouvez vouloir :

  • aider votre utilisateur, en lui proposant une liste de choix
  • tout en lui permettant d'effectuer une saisie libre.

Par exemple, pensons à la saisie d'une adresse E-Mail lors de la rédaction d'un courier électronique[1] :

  • l'utilisateur peut commencer à saisir une adresse
  • vous pouvez lui proposer une liste issue de son carnet d'adresses, filtrée par sa saisie
  • il peut :
    • soit sélectionner l'une des adresses proposées,
    • soit en saisir une autre.

Cet article va nous permettre d'apprendre à mettre en place ce type de système de propositions, en utilisant le Framework JavaScript Scriptaculous.


Script.aculo.us :: Ajax.Autocompleter

Scriptaculous est une bibliothèque d'interface JavaScript basée sur le framework prototype.js, que nous avons déjà utilisé dans d'autres articles.

Cette bibliothèque propose un composant qui vous permettra :

  • de définir un champ de saisie dans un formulaire
  • de proposer à l'utilisateur des suggestions correspondant à sa saisie
  • en chargeant ces suggestions depuis un serveur web via une requête Ajax.

Ce composant est nommé Ajax.Autocompleter.

Le principe d'utilisation est relativement simple. Vous avez besoin de trois éléments :

  • un formulaire HTML,
  • quelques lignes de JavaScript pour le rendre dynamique,
  • et un script sur un serveur, qui sera appelé via une requête Ajax.


Formulaire HTML

Pour fonctionner, Ajax.Autocompleter se base sur :

  • un formulaire HTML - un champ input text,
  • et un élément au sein duquel seront affichées les propositions - un div, en général.

Pour notre premier exemple, nous considérerons que vous souhaitez permettre à un utilisateur de saisir le nom d'un département, avec auto-complétion.

La portion de code HTML correspondante serait la suivante :

<form action="" method="get">
    Saisissez un nom de département : 
        <input type="text" id="departement" name="departement"/>
    <div id="departement_propositions" class="autocomplete"></div>
</form>


Initialisation de l'objet Ajax.Autocompleter

La seconde étape est de créer une instance d'objet Ajax.Autocompleter, en lui indiquant qu'il devra travailler sur la portion de formulaire que nous venons de créer :

// Instanciation de la classe Autocompleter, pour le champ de saisie "departement"
new Ajax.Autocompleter(
    "departement",   // id du champ de formulaire
    "departement_propositions",  // id de l'élément utilisé pour les propositions
    "serveur-departement.php",  // URL du script côté serveur
    {
        paramName: 'departement',  // Nom du paramètre reçu par le script serveur
        minChars: 1   // Nombre de caractères minimum avant que des appels serveur ne soient effectués
    });

Le principe est le suivant :

  • vous créez une instance d'objet Ajax.Autocompleter
  • le premier paramètre est l'identifiant du champ de formulaire dans lequel l'utilisateur saisira le texte à auto-compléter
  • le second est l'identifiant de l'élément HTML au sein duquel seront affichées les propositions
  • le troisième est l'adresse du script côté serveur qui recevra en paramètre la saisie, et devra retourner la liste des propositions
  • et le dernier est une série d'options. Ici, nous passons les suivantes :
    • paramName : Le nom du paramètre qui sera reçu par le serveur.
    • minChars : nombre de caractères minimum avant qu'un appel serveur ne soit effectué. Pour une liste de 100 départements en France, on peut proposer des suggestions d'auto-complétion dès qu'un caractère est saisi.

Par défaut, la saisie de l'utilisateur sera envoyée en POST au script serveur.


Script serveur renvoyant les suggestions

Enfin, la dernière étape est de développer un script côté serveur, qui sera appelé par l'objet Ajax.Autocompleter lorsque l'utilisateur saisira du texte dans le champ de saisie.

Ce script recevra en entrée la saisie de l'utilisateur, et devra renvoyer en sortie une liste composée des différentes suggestions correspondant à sa saisie - de manière générale, une liste des possibilités commençant par celle-ci.

Scriptaculous attend que les suggestions soient renvoyées au sein d'une liste HTML : un élément <ul> regroupant plusieurs éléments <li> - chacun correspondant à une suggestion.

Dans le cas de notre exemple, le serveur reçoit en POST une variable nommée "departement" (le paramName précisé à l'instanciation de la classe Ajax.Autocompleter).
A lui de déterminer quoi renvoyer.

Par exemple, notre script serveur pourrait être le suivant :
(Algorithme extrêmement naïf : si la saisie correspond au début d'un département, alors on le renvoit. Un tel algorithme serait catastrophique en terme de performances sur un volume plus gros - et stocker des milliers de lignes directement dans un tableau PHP ne tiendrait rapidement plus dans la limite mémoire autorisée pour vos scripts)

<?php
    $departements = array(
        'Ain',
        // ...
        'Ille-et-Vilaine',
        'Indre',
        'Indre-et-Loire',
        'Isère',
        // ...
        'Sarthe',
        // ...
        'La Réunion',
    );
    
    echo "<ul>\n";
    foreach ($departements as $departement)
    {
        if (stripos($departement, $_POST['departement']) === 0)
        {
            echo "    <li>$departement</li>\n";
        }
    }
    echo "</ul>";
?>

(Pour éviter d'avoir un code source trop long, j'ai coupé la liste des départements - vous la trouverez, au besoin, sur le site de l'INSEE.)

Si l'utilisateur saisit un "i", le serveur enverra en retour :

<ul>
    <li>Ille-et-Vilaine</li>
    <li>Indre</li>
    <li>Indre-et-Loire</li>
    <li>Isère</li>
</ul>

Ce qui correspond bien à la liste des départements français commençant par... "i".

Et s'il affine sa saisie : "in", le serveur renverra, comme attendu :

<ul>
    <li>Indre</li>
    <li>Indre-et-Loire</li>
</ul>

A tout moment, l'utilisateur peut cliquer sur l'une des propositions, et celle-ci remplacera alors la saisie dans le champ de formulaire.
Le choix d'un élément est aussi possible au clavier.


Autocompléter avec style

Forcément, avec les styles par défaut, le rendu n'est pas des plus appréciables : Ajax.Autocompleter : sans style CSS

Mais, heureusement, Scriptaculous permet de définir des styles pour embellir tout ça.

Au moment où nous avons défini l'élément HTML contenant la liste de suggestions, nous lui avons affecté une classe CSS :

<div id="departement_propositions" class="autocomplete"></div>

Il suffit de définir les styles souhaités, en se basant sur de div, et sur cette class, "autocompleter", dans notre cas.
Par exemple, nous pourrions définir les styles suivants :

div.autocomplete {
  position: absolute;
  width: 500px;
  background-color: white;
  border: 1px solid #888;
  margin: 0px;
  padding: 0px;
}

div.autocomplete ul {
  list-style-type: none;
  margin: 0px;
  padding: 0px;
  max-height: 20em;
  overflow: auto;
}

div.autocomplete ul li.selected {
    background-color: #ffb;
}

div.autocomplete ul li {
  list-style-type:none;
  display: block;
  margin: 0;
  padding: 2px;
  cursor: pointer;
}

Et voici le rendu : Ajax.Autocompleter : avec style CSS

Tout de suite moins spartiate... Et libre à vous d'améliorer cela pour l'intégrer à votre charte graphique !


Nous verrons dans un futur article que les fonctionnalités offertes par Ajax.Autocompleter ne s'arrêtent pas là : nous verrons comment

  • exploiter les données saisies par l'utilisateur,
  • en lui affichant des suggestions plus détaillées,
  • et le tout avec des données correspondant à un cas "réel".

A bientôt, donc !


Note

[1] Si vous utilisez parfois gmail, vous reconnaitrez ce dont je parle, et son utilité - remarque valable aussi pour la plupart des clients mail en interface graphique