Suggestion de remplissage

La suggestion de remplissage d'un champ se fait avec l'attribut autocomplete. L'utilisation de cet attribut permet d'afficher des suggestions qui correspondent à une chaîne de caractères saisis en temps réel. Elle permet ensuite de sélectionner une suggestion pour terminer sa saisie rapidement avec une valeur exacte, ou alors de continuer à saisir des caractères pour affiner les options proposées.

Présentation

Code HTML

L’autocomplétion doit pouvoir fonctionner sans javascript. On va donc utiliser les éléments natifs du HTML pour proposer une liste de choix avec l’élément HTML datalist.

<label for="pays">Pays</label>
<input class="form-control" list="datalistOptions" id="pays" placeholder="Rechercher un pays...">
<datalist id="datalistOptions">
  <option value="Allemagne">
   <option value="Espagne">
   <option value="France">
   <option value="Italie">
   <option value="Portugal">
</datalist>

L’élément HTML datalist est de mieux en mieux supporté par les navigateurs (pour peu qu’il ne soit pas utilisé pour des champs de type time ou date).
Si on ne veut pas utiliser l’élément HTML datalist, on pourra utiliser alors l’élément select et du javascript. l’élément select aura alors les options suivantes Pour masquer cette liste déroulante sans empêcher l’envoi de sa valeur au serveur :

  • sr-only pour rendre la liste déroulante invisible aux personnes voyantes - elle sera pour autant lisible pour les synthèses vocales et va donc rajouter l’attribut qui suit ;
  • aria-hidden="true" pour la rendre invisible pour les personnes qui utilisent un lecteur d’écran ;
  • tabindex="-1" pour empêcher les personnes naviguant au clavier de positionner le focus dessus.
 <label for="pays">Pays</label>
 <select name="pays" id="pays" class="sr-only" aria-hidden="true" tabindex="-1">
   <option value="">Sélectionner</option>
   <option value="Allemagne">Allemagne</option>
   <option value="Espagne">Espagne</option>
   <option value="France">France</option>
   <option value="Italie">Italie</option>
   <option value="Portugal">Portugal</option>
 </select>

Code javascript

Le javascript recommandé est celui du composant « autocomplete » accessible du gouvernement britannique.

Exemple avec appel à une API

Visuel

Pour faciliter le remplissage de champs d'adresse, on peut aussi recourir à l'api d'adresse de l'État français.

Rechercher une adresse

Résultat de la recherche

Code HTML

<form action="./" method="GET">
<h4>Rechercher une adresse</h4>       
<div class="autoComplete_wrapper">
<label for="autoComplete">Rechercher une adresse</label>
<div>
<input id="autoComplete" type="search" dir="ltr" spellcheck=false autocorrect="off" autocomplete="off" autocapitalize="off">
<button type="reset" class="autoReset">Effacer</button>
</div>
</div>
<h4 class="formresult">Résultat de la recherche</h4>
<div class="resultat">
<div>
<label for="adress">Adresse</label><input id="adress">
<label for="postcode">Code postal</label><input id="postcode">
<label for="city">Commune</label><input id="city"> 
</div>
<div>
<label for="housenumber">Numéro</label><input id="housenumber">
<label for="street">Rue</label><input id="street">  
<label for="citycode">Code INSEE de la commune</label><input id="citycode">
</div> 
<div>
<label for="context">Département et région</label><input id="context">
<label for="lon">Longitude</label><input id="lon">  
<label for="lat">Latitude</label><input id="lat">
</div> 
</div>
</form>

Code javascript

Le code présenté est celui permettant de récupérer les informations de l’API et de remplir les champs concernés.

var myobject = [];
const adress = document.querySelector("#adress");
const postcode = document.querySelector("#postcode");
const citycode = document.querySelector("#citycode");
const city = document.querySelector("#city");
const housenumber = document.querySelector("#housenumber");
const street = document.querySelector("#street");
const context = document.querySelector("#context");
const lon = document.querySelector("#lon");
const lat = document.querySelector("#lat");
const autoCompleteJS = new autoComplete({
  selector: "#autoComplete",
  placeHolder: "Recherche adresse...",
  data: {
    src: async () => {
      const term = document.querySelector("#autoComplete").value;
      if (term) {
        const response = await fetch(
          `https://api-adresse.data.gouv.fr/search/?q=${term}`
        );
        const json = await response.json();
        myobject = json.features.map(function (el) {
          return {
            label: el.properties.label,
            value: el.properties.label,
            housenumber: el.properties.housenumber,
            name: el.properties.name,
            postcode: el.properties.postcode,
            citycode: el.properties.citycode,
            city: el.properties.city,
            context: el.properties.context,
            type: el.properties.type,
            street: el.properties.street,
            lat: el.geometry.coordinates[1],
            lon: el.geometry.coordinates[0],
            boundingbox: null,
          };
        });
        adresses = myobject.map((el) => el.value);
        console.log(adresses);
      } else {
        adresses = [];
      }
      // ... other code
      return adresses;
    },
    // src: ["Sauce - Thousand Island", "Wild Boar - Tenderloin", "Goat - Whole Cut"],
    cache: false,
  },
  resultsList: {
    element: (list, data) => {
      if (!data.results.length) {
        // Create "No Results" message element
        const message = document.createElement("div");
        // Add class to the created element
        message.setAttribute("class", "no_result");
        // Add message text content
        message.innerHTML = `<span>Aucun résultat trouvé pour "${data.query}"</span>`;
        // Append message element to the results list
        list.prepend(message);
      }
    },
    noResults: true,
  },
  resultItem: {
    highlight: true,
  },
  events: {
    input: {
      selection: (event) => {
        const selection = event.detail.selection.value;
        autoCompleteJS.input.value = selection;
        var result = myobject.find(
          (el) => el.value == event.detail.selection.value
        );
        if (result) {
          adress.value = result.name;
          postcode.value = result.postcode;
          citycode.value = result.citycode;
          city.value = result.city;
          housenumber.value = result.housenumber;
          street.value = result.street;
          context.value = result.context;
          lon.value = result.lon;
          lat.value = result.lat;
        } else {
          adress.value = "";
          postcode.value = "";
          citycode.value = "";
          city.value = "";
          housenumber.value = "";
          street.value = "";
          context.value = "";
          lon.value = "";
          lat.value = "";
        }
      },
    },
  },
});