Auto-completion HTML : le code JavaScript le plus simple

En quelques lignes, sans framework, ni expression régulière...

Un script pour compléter un mot que l'utilisateur veut entrer dans un champ de texte, à partir des mots disponibles dans une liste.

Le code de l'auto-complétion fait exactement 10 lignes!

Démonstration

Liste de mots disponibles pour la démonstration: log, login, logon, logout, logoff, logged...

Voici le code source complet...

Code HTML

<input type="text" value="Tapez un mot..." onKeyUp="check(this)" onChange="check(this)">

Code JavaScript

var base= ['log', 'login', 'logon', 'logout', 'logoff', 'logged'];

function check(field) {
  var name = field.value;
  var l = name.length;
  var idx = base.indexOf(name);
  if(idx == -1) {
    var tempo = base.filter(function(x) {
      return x.substr(0, l) == name;
    });
    if(tempo.length != 1) return;
    name = tempo[0];	
    field.value = name;
  }
  var content = name + " trouvé.";
  document.getElementById("storage").innerHTML=content;
}

Explications...

onKeyUp="check(this)" onChange="check(this)"

Chaque fois qu'une lettre est tapée, la fonction check est appelée.

var idx = base.indexOf(name);
if(idx == -1) {
  ...
}

On regarde d'abord si le mot tapé est dans la liste. Si c'est le cas, on affiche le résultat.

var tempo = base.filter(function(x) {
return x.substr(0, l) == name;
});

Sinon on compare ce qui est tapé avec les premières lettres de chaque mot de la liste. Pour ce faire on applique un filtre qui sélectionne tous les mots qui commencent par le mot tapé (le second paramètre de substr est la lettre L, la longueur du mot tapé, non le chiffre 1) .

if(tempo.length != 1) return;

Le filtre retourne un tableau, tempo. On évalue le nombre d'éléments.
Si length = 0, aucun mot ne commence par les mêmes lettres, on sort.
Si length > 1 plusieurs mots commencent par ces lettres, on sort aussi pour que l'utilisateur tape une lettre de plus.

name = tempo[0];	
field.value = name;

Quand length = 1, un seul mot dans la liste commence par les lettres entrées, on complète alors le mot dans le champ de texte, et on passe au résultat, pour la démonstration on affiche "trouvé" dans le champ de résultat, mais l'utilisation du résultat dépendra de l'application que le webmaster veut en faire...

Un exemple d'application? Cliquez sur le bouton "dictionnaire" en haut à droite de la page...

Compatibilité avec les anciens navigateurs

La méthode filter est implémentée dans ECMAScript 1.6. La méthode indexOf de array n'est implémentée que depuis Internet Explorer 9, il faut changer le code si on veut supporter les versions plus anciennes.
Pour les anciens navigateurs, on doit remplacer indexOf et filter par des boucles et on peut même l'optimiser en une seule boucle, démonstration ci-dessous...

Démonstration

Code source

function check(field) {
  var name = field.value;
  var l = name.length;
  var last = name;
  function AC_indexOf()
  {
    var ctr=0;
    for(var i = 0; i < base.length; i++)
    {
      var next = base[i];
      if(name==next) return 1;
      if(name==next.substr(0, l)) { last=next; ctr++;}
    }
    return ctr;
  }
  var ctr = AC_indexOf();
  if(ctr != 1) return;
  field.value = last;
  var content = last + " trouvé.";
  document.getElementById("storage").innerHTML=content;
}

Ce code est probablement plus lent, ce que l'on ne peut constater qu'avec une liste de mots importante... Mais il fonctionne même avec Internet Explorer 5!