Contrôles d’autocomplétion légers avec la liste de données HTML5

Dans ce tutoriel, nous allons plonger en profondeur dans l’élément HTML5 peu utilisé <datalist>. Il permet d’implémenter un contrôle de formulaire autocomplete léger, accessible et compatible avec tous les navigateurs sans avoir besoin de JavaScript.

Quel est le problème avec <select>?

Les contrôles HTML5 <select> sont idéaux lorsque vous souhaitez que l’utilisateur choisisse parmi un petit nombre d’options. Ils sont moins pratiques lorsque :

  • il y a beaucoup d’options, comme les pays ou les titres de poste
  • l’utilisateur souhaite saisir sa propre option qui n’est pas dans la liste

La solution évidente est un contrôle autocomplete. Cela permet à l’utilisateur de saisir quelques caractères, ce qui limite les options disponibles pour une sélection plus rapide.

<select> sautera à la bonne position lorsque vous commencerez à taper, mais ce n’est pas toujours évident. Cela ne fonctionnera pas sur tous les appareils (comme les écrans tactiles), et cela se réinitialise dans une seconde ou deux.

Les développeurs ont souvent recours à l’un des nombreux solutions alimentées par JavaScript, mais un contrôle autocomplete personnalisé n’est pas toujours nécessaire. L’élément HTML5 <datalist> est léger, accessible et n’a pas de dépendances JavaScript. Vous avez peut-être entendu dire qu’il est buggé ou manque de support. Ce n’est pas vrai en 2021, mais il existe des incohérences et des mises en garde entre les navigateurs.

<datalist> Démarrage rapide

Choisir son pays dans une liste comportant plus de 200 options est un candidat idéal pour un contrôle d’autocomplétion. Définissez un <datalist> avec des éléments enfants <option> pour chaque pays directement dans une page HTML :

<datalist id="countrydata">
  <option>Afghanistan</option>
  <option>Åland Islands</option>
  <option>Albania</option>
  <option>Algeria</option>
  <option>American Samoa</option>
  <option>Andorra</option>
  <option>Angola</option>
  <option>Anguilla</option>
  <option>Antarctica</option>
  ...etc...
</datalist>

L’identifiant du datalist peut ensuite être référencé par un attribut list dans n’importe quel champ <input> :

<label for="country">country</label>

<input type="text"
  list="countrydata"
  id="country" name="country"
  size="50"
  autocomplete="off" />

De manière déroutante, il est préférable de définir autocomplete="off". Cela garantit que l’utilisateur voit les valeurs dans le <datalist> mais pas les valeurs qu’il a précédemment entrées dans le navigateur.

Le résultat :

C’est le rendu par défaut dans Microsoft Edge. D’autres applications mettent en œuvre une fonctionnalité similaire, mais l’apparence varie entre les plateformes et les navigateurs.

<option> Options

Utiliser l’étiquette comme enfant texte d’un <option> est courant :

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

Utiliser un attribut value produit des résultats identiques :

<datalist id="mylist">
  <option value="label one" />
  <option value="label two" />
  <option value="label three" />
</datalist>

Remarque : la barre oblique fermante /> est facultative dans HTML5, bien qu’elle puisse aider à prévenir les erreurs de codage.

Vous pouvez également définir une valeur en fonction d’une étiquette choisie en utilisant l’un des formats suivants.

Option 1 :

<datalist id="mylist">
  <option value="1">label one</option>
  <option value="2">label two</option>
  <option value="3">label three</option>
</datalist>

Option 2 :

<datalist id="mylist">
  <option value="1" label="label one" />
  <option value="2" label="label two" />
  <option value="3" label="label three" />
</datalist>

Dans les deux cas, le champ d’entrée est défini sur 1, 2 ou 3 lorsqu’une option valide est choisie, mais l’interface varie entre les navigateurs :

  • Chrome affiche une liste avec à la fois la valeur et le libellé. Seule la valeur reste une fois qu’une option est choisie.
  • Firefox affiche une liste avec le libellé uniquement. Il bascule vers la valeur une fois qu’une option est choisie.
  • Edge affiche uniquement la valeur.

L’exemple de CodePen suivant montre toutes les variations:

Voir le Pen
Exemples d’autocomplétion HTML5 <datalist>
par SitePoint (@SitePoint)
sur CodePen.

Les implémentations évolueront, mais pour l’instant, je vous conseille de ne pas utiliser une valeur et un libellé car cela risque de confondre les utilisateurs. (Une astuce est discutée ci-dessous.)

<datalist> Prise en charge des navigateurs et remplacement

L’élément <datalist> est bien pris en charge dans les navigateurs modernes ainsi qu’Internet Explorer 10 et 11:

Il existe plusieurs notes d’implémentation, mais elles n’affecteront pas la plupart des utilisations. Le pire qui puisse arriver est qu’un champ revienne à une saisie de texte standard.

Si vous devez absolument prendre en charge IE9 et versions antérieures, il existe un schéma de remplacement qui utilise un <select> standard en conjonction avec une saisie de texte lorsque le <datalist> échoue. Adaptez l’exemple de pays :

<label for="country">country</label>

<datalist id="countrydata">

  <select name="countryselect">
    <option></option>
    <option>Afghanistan</option>
    <option>Åland Islands</option>
    <option>Albania</option>
    <option>Algeria</option>
    <option>American Samoa</option>
    <option>Andorra</option>
    <option>Angola</option>
    <option>Anguilla</option>
    <option>Antarctica</option>
    ...etc...
  </select>

  <label for="country">or other</label>

</datalist>

<input type="text"
  id="country" name="country"
  size="50"
  list="countrydata"
  autocomplete="off" />

Voir le Pen
HTML5 <datalist> autocomplete fallback
par SitePoint (@SitePoint)
sur CodePen.

Dans les navigateurs modernes, les éléments <option> font partie du <datalist> et l’étiquette “ou autre” n’est pas affichée. Cela ressemble à l’exemple ci-dessus, mais une valeur de formulaire countryselect sera définie sur une chaîne vide.

Dans IE9 et versions antérieures, les deux champs de saisie de texte (très longs) <select> sont actifs:

Les deux valeurs pourraient être entrées dans les anciens IEs. Votre application doit soit:

  • décider lequel est le plus valide, ou
  • utiliser une petite fonction JavaScript pour réinitialiser l’un quand l’autre est modifié

Utilisation de <datalist> sur des contrôles non textuels

Les navigateurs basés sur Chrome peuvent également appliquer des valeurs <datalist> à:

  1. Une entrée avec le type de "date". L’utilisateur peut choisir parmi une gamme d’options définies comme valeurs YYYY-MM-DD mais présentées dans leur format local.

  2. Une entrée de type "color". L’utilisateur peut choisir parmi une sélection d’options de couleur définies comme des valeurs hexadécimales à six chiffres (les valeurs à trois chiffres ne fonctionnent pas).

  3. Une entrée de type "range". La barre de glissement affiche des marques de graduation, bien que cela ne limite pas la valeur qui peut être entrée.

Voir le Pen
HTML5 <datalist> sur d’autres types d’entrée
par SitePoint (@SitePoint)
sur CodePen.

<datalist> Style CSS

Si vous avez déjà lutté pour styliser une <select> boîte, … vous aviez it easy!

Un <input> peut être stylisé normalement, mais une <datalist> liée et ses éléments enfants <option> ne peuvent pas être stylisés en CSS. L’affichage de la liste est entièrement déterminé par la plateforme et le navigateur.

I hope this situation improves, but for now, a solution is proposed at MDN which:

  1. remplace le comportement par défaut du navigateur
  2. traite effectivement la <datalist> comme un <div> afin qu’elle puisse être stylisée en CSS
  3. reproduit toutes les fonctionnalités d’autocomplétion en JavaScript

I’ve enhanced it further and the code is available on GitHub. To use it, load the script anywhere in your HTML page as an ES6 module. The jsDelivr CDN URL can be used:

<script src="https://cdn.jsdelivr.net/npm/datalist-css/dist/datalist-css.min.js"></script>

Ou vous pouvez l’installer avec npm si vous utilisez un bundler:

npm install datalist-css

Vos éléments <datalist> doivent utiliser le format <option>value</option>. Par exemple:

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

Note : <option value="value" /> ne peut pas être utilisé, car cela aboutit à un élément vide qui ne peut pas être stylisé !

Le CSS peut ensuite être ajouté pour styliser certains ou tous les éléments <datalist> et <option>. Par exemple:

datalist {
  position: absolute;
  max-height: 20em;
  border: 0 none;
  overflow-x: hidden;
  overflow-y: auto;
}

datalist option {
  font-size: 0.8em;
  padding: 0.3em 1em;
  background-color: #ccc;
  cursor: pointer;
}

/* style de l'option active */
datalist option:hover, datalist option:focus {
  color: #fff;
  background-color: #036;
  outline: 0 none;
}

Exemple:

Voir le Pen
Stylisation CSS de l’autocomplétion HTML5 <datalist>
par SitePoint (@SitePoint)
sur CodePen.

Le style fonctionne, mais vaut-il la peine d’effectuer cet effort ? Je doute que ce soit le cas…

  • Réimplémenter les contrôles standard du navigateur (clavier, souris et tactile) avec une accessibilité raisonnable est difficile. L’exemple MDN ne prend pas en charge les événements clavier et, bien que j’aie essayé d’améliorer cela, il y aura inévitablement des problèmes sur certains appareils.
  • Vous comptez sur 200 lignes de JavaScript pour résoudre un problème de CSS. Cela minifie à 1,5kB, mais pourrait introduire des problèmes de performance si vous aviez besoin de nombreux éléments <datalist> longs sur la même page.
  • Si JavaScript est une exigence, serait-il préférable d’utiliser un composant JavaScript plus joli, plus cohérent et éprouvé au combat?

Le contrôle bascule vers un <datalist> HTML5 standard sans style lorsque JavaScript échoue, mais c’est un avantage mineur.

Créer un <datalist> amélioré par Ajax

En supposant que votre concepteur accepte les différences de style des navigateurs, il est possible d’améliorer la fonctionnalité standard du <datalist> à l’aide de JavaScript. Par exemple :

  1. Implémenter une validation optionnelle qui ne permet qu’une valeur connue dans le <datalist>.
  2. Définir les éléments <option> à partir des données renvoyées par les appels Ajax aux API de recherche.
  3. Définir d’autres valeurs de champ lorsqu’une option est choisie. Par exemple, en sélectionnant « États-Unis d’Amérique », cela définit « US » dans une entrée cachée.

Le code doit principalement redéfinir les éléments <option>, bien qu’il y ait plusieurs considérations de codage :

  • Une requête API Ajax ne devrait se produire qu’après qu’un nombre minimum de caractères ait été entré.
  • Les événements de saisie doivent être débogués. Autrement dit, un appel Ajax n’est déclenché que lorsque l’utilisateur a cessé de taper pendant au moins une demi-seconde.
  • Les résultats de la requête doivent être mis en cache pour ne pas être obligé de répéter ou de parser des appels identiques.
  • Les requêtes inutiles doivent être évitées. Par exemple, l’entrée de « un » renvoie 12 pays. Il n’est pas nécessaire de faire d’autres appels Ajax pour « unit » ou « united » car toutes les options résultantes sont contenues dans les 12 résultats originaux.

I’ve created a standard Web Component for this, and the code is available on GitHub. The CodePen example below allows you to select a valid country after entering at least two characters. A music artist autocomplete then returns artists who originated in that country with names matching the search string:

Voir le Pen
HTML5 <datalist> avec autocomplétion Ajax
par SitePoint (@SitePoint)
sur CodePen.

Pour l’utiliser dans votre propre application, chargez le script n’importe où dans votre page HTML en tant que module ES6. L’URL du CDN jsDelivr peut être utilisée:

<script src="https://cdn.jsdelivr.net/npm/datalist-ajax/dist/datalist-ajax.min.js"></script>

Ou vous pouvez l’installer avec npm si vous utilisez un bundler:

npm install datalist-ajax

Créez un élément <auto-complete> avec un enfant <input> pour utiliser comme champ d’entrée de données. Par exemple, la recherche de pays utilise ceci:

<label for="country">country lookup:</label>

<auto-complete
  api="https://restcountries.eu/rest/v2/name/${country}?fields=name;alpha2Code;region"
  resultname="name"
  querymin="2"
  optionmax="50"
  valid="please select a valid country"
>
  <input type="text" id="country" name="country" size="50" required />
</auto-complete>

Attributs de l’élément <auto-complete>:

attribute description
api the REST API URL (required)
resultdata the name of the property containing a result array of objects in the returned API JSON (not required if only results are returned)
resultname the name of the property in each result object which matches the search input and is used for datalist <option> elements (required)
querymin the minimum number of characters to enter before a search is triggered (default: 1)
inputdelay the minimum time to wait in milliseconds between keypresses before a search occurs (default debounce: 300)
optionmax the maximum number of autocomplete options to show (default: 20)
valid if set, this error message is shown when an invalid value is selected

L’URL REST doit contenir au moins un identifiant ${id}, qui est remplacé par la valeur définie dans l’<input> ayant cet id. Dans l’exemple ci-dessus, ${country} dans l’URL api fait référence à la valeur dans l’enfant <input>, qui a un id de "country". L’URL utilisera normalement l’entrée enfant, mais n’importe quel autre champ sur la page peut être référencé.

L’API restcountries.eu renvoie un objet unique ou un tableau d’objets contenant des données sur les pays. Par exemple:

[
  {
    "name": "Cyprus",
    "alpha2Code": "CY",
    "region": "Europe"
  },
  {
    "name": "Sao Tome and Principe",
    "alpha2Code": "ST",
    "region": "Africa"
  },
  {
    "name": "Andorra",
    "alpha2Code": "AD",
    "region": "Europe"
  }
]

L’attribut resultdata n’a pas besoin d’être défini car c’est la seule donnée renvoyée (il n’y a pas d’objet enveloppant). L’attribut resultname doit être défini sur "name" car cette propriété est utilisée pour remplir les éléments de liste de données <option>.

D’autres champs peuvent être automatiquement remplis lorsqu’une option est choisie. Les entrées suivantes reçoivent les données des propriétés "alpha2Code" et "region" car un attribut data-autofill a été défini:

<input data-autofill="alpha2Code" type="text" id="countrycode" name="countrycode" readonly />

<input data-autofill="region" type="text" id="region" name="region" readonly />

Fonctionnement de datalist-ajax

Vous pouvez sauter cette section si vous préférez ne pas lire 230 lignes de code et garder le charme intact !

Le code initial crée un nouveau `` à l’intérieur du ``, qu’il attache à l’élément enfant `` en utilisant un attribut `list`. Un gestionnaire d’événements `input` surveille le `` et appelle une fonction `runQuery()` lorsqu’un nombre minimal de caractères a été entré et que l’utilisateur n’est plus en train de taper.

runQuery() construit l’URL de l’API à partir des données du formulaire et effectue un appel Ajax en utilisant le Fetch API. Le JSON retourné est ensuite analysé, puis un fragment DOM réutilisable contenant des éléments `` est construit et placé dans un cache.

A datalistUpdate() function is called, which updates the <datalist> with the appropriate cached DOM fragment. Further calls to runQuery() avoid Ajax calls if a query has already been cached or a previous query can be used.

A change event handler also monitors the <input>, which is triggered when focus is moved from the field and the value has been modified. The function checks that the value matches a known option and, if necessary, uses the Constraint Validation API to show the error message provided in the valid attribute.

En supposant qu’une option valide a été choisie, la fonction de gestionnaire de changement remplit tous les champs avec des attributs `data-autofill` correspondants. Une référence aux champs d’auto-complétion est conservée afin qu’ils puissent être réinitialisés si une option invalide est entrée par la suite.

Notez que le shadow DOM est pas utilisé. Cela garantit que les éléments `` (et ``) auto-complétés peuvent être stylisés par CSS et accessibles par d’autres scripts si nécessaire.

Dunkin’ `

`Le `` HTML5 présente des limitations mais est idéal si vous avez besoin d’un champ auto-complété simple et indépendant d’un framework. Le manque de support CSS est regrettable, mais les fournisseurs de navigateurs pourraient éventuellement corriger cette erreur.

Tout le code et les exemples présentés dans ce tutoriel peuvent être adoptés pour vos propres projets.

FAQs sur les contrôles d’autocomplétion légers avec la dataliste HTML5

Qu’est-ce que l’élément datalist HTML5 et comment fonctionne-t-il?

L’élément datalist HTML5 est une liste prédéfinie d’options pour un élément d’entrée. Il fournit une fonctionnalité « autocomplete » sur les éléments de formulaire. L’élément datalist utilise l’attribut id pour l’associer à un élément d’entrée spécifique. L’élément d’entrée utilise l’attribut list pour identifier la datalist. À l’intérieur de la datalist, vous pouvez définir des éléments option qui représentent les options disponibles pour le champ d’entrée.

Comment puis-je utiliser la datalist HTML5 pour l’autocomplétion?

Pour utiliser la datalist HTML5 pour l’autocomplétion, vous devez associer la datalist à un champ d’entrée. Cela se fait en ajoutant l’attribut list au champ d’entrée et en définissant sa valeur sur l’id de la datalist. Le navigateur suggérera alors des options d’autocomplétion en fonction de l’entrée de l’utilisateur et des options définies dans la datalist.

Puis-je utiliser l’élément datalist HTML5 dans tous les navigateurs?

L’élément datalist HTML5 est pris en charge dans la plupart des navigateurs modernes, y compris Chrome, Firefox, Safari et Edge. Cependant, il n’est pas pris en charge dans Internet Explorer 9 et les versions antérieures. Vous pouvez vérifier la compatibilité actuelle du navigateur sur des sites comme Can I Use.

Comment puis-je styliser les options de la datalist HTML5?

Malheureusement, les options de style pour l’élément datalist HTML5 sont assez limitées. L’apparence de la liste déroulante est contrôlée par le navigateur et ne peut pas être facilement personnalisée avec CSS. Cependant, vous pouvez styliser le champ d’entrée associé à la datalist.

Puis-je utiliser plusieurs datalists pour un seul champ d’entrée?

Non, vous ne pouvez pas associer plusieurs datalists à un seul champ d’entrée. L’attribut list du champ d’entrée ne peut prendre qu’un seul id, qui correspond à un datalist. Si vous avez besoin de fournir plusieurs ensembles d’options, vous devrez peut-être utiliser JavaScript pour modifier dynamiquement les options en fonction de l’entrée de l’utilisateur.

Puis-je utiliser le datalist HTML5 avec d’autres types d’entrée?

Oui, le datalist HTML5 peut être utilisé avec divers types d’entrée, y compris texte, recherche, url, tel, email, date, mois, semaine, heure, datetime-local, nombre, gamme et couleur. Cependant, la fonctionnalité de complétion automatique pourrait ne pas fonctionner comme prévu avec certains types d’entrée comme la plage ou la couleur.

Puis-je utiliser le datalist HTML5 avec un élément select?

Non, le datalist HTML5 ne peut pas être utilisé avec un élément select. Le datalist est conçu pour fournir des suggestions de complétion automatique pour un champ d’entrée, tandis que l’élément select fournit une liste déroulante d’options. Si vous avez besoin d’une liste déroulante, vous devriez utiliser l’élément select à la place.

Puis-je utiliser JavaScript avec le datalist HTML5?

Oui, vous pouvez utiliser JavaScript avec le datalist HTML5 pour ajouter, supprimer ou modifier dynamiquement les options. Cependant, gardez à l’esprit que le datalist ne prend pas en charge les événements comme onchange ou onclick sur ses options. Vous devez ajouter les écouteurs d’événements au champ d’entrée associé à la place.

Puis-je utiliser le datalist HTML5 pour un champ de recherche?

Oui, le datalist HTML5 peut être une excellente option pour un champ de recherche. Il peut fournir des suggestions de complétion automatique en fonction de l’entrée de l’utilisateur, ce qui peut améliorer l’expérience utilisateur. Cependant, vous devez remplir manuellement le datalist avec les termes de recherche possibles.

Puis-je utiliser la dataliste HTML5 avec un textarea?

Non, la dataliste HTML5 ne peut pas être utilisée avec un textarea. La dataliste est conçue pour fournir des suggestions de complétion automatique pour un champ d’entrée, et non pour un textarea. Si vous avez besoin de fonctionnalités de complétion automatique pour un textarea, vous devrez peut-être utiliser une bibliothèque JavaScript ou créer votre propre solution.

Source:
https://www.sitepoint.com/html5-datalist-autocomplete/