11496 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,

Pour expliquer rapidement ma situation, j’ai un champ de recherche (input text) qui permet de sélectionner une phrase ou un mot stockés dans une base de données XML, à l’aide d’une autocomplétion.

Je voudrais savoir comment compléter l’input text avec le premier résultat de l’autocomplétion, en affichant la fin de ce résultat de l’autre côté du curseur clignotant, de la même façon que google.

Pour info, j’ai réussi à simuler ce résultat avec une fonction JavaScript. Le problème c’est que le temps que la fonction s’exécute, le résultat met une demi-seconde à se réactualiser, et pendant ce temps le texte saisi passe par dessus le texte qui a le rôle de compléter la requête. Bref, c’est un peu dégueulasse. Je me demande si HTML5 a prévu quelque chose pour ça, je n’ai pas l’impression que JavaScript est la solution, ou alors je ne m’y prends pas bien.

Merci.
a écrit :
Je voudrais savoir comment compléter l’input text avec le premier résultat de l’autocomplétion, en affichant la fin de ce résultat de l’autre côté du curseur clignotant, de la même façon que google.

Google ne fait pas de l'autocompletion correctement, alors il vaudrait mieux éviter de l'imiter.

En fait, il ne faut pae insérer l'autocompletion à droite du curseur et le laisser inchangé à sa place, mais bien insérer l'autocompletion à droite du curseur et sélectionner la portion qui vient d'avoir été autocomplétée

Cette dernière façon de faire cumule tous les avantages :
+ Soit l'utilisateur n'a que faire de ton autocompletion ou bien elle ne correspond pas à ce qu'il veut. Dans ce cas la saisie d'une seule lettre fait disparaître ta proposition.
+ Si l'utilisateur est d'accord avec ta proposition, il a juste à appuyer sur fin pour continuer sa saisie, ou enter pour l'envoyer directement. Pour parfaire la chose tu peux faire en sorte que la touche espace ou les ponctuations valident aussi la completion du mot en cours au lieu d'effacer la sélection, comme dans un SMS sur un téléphone.

Si tu te contentes d'ajouter ta proposition sans la sélectionner, alors :
+ Soit elle correspond aux attentes et alors il faut quand même appuyer sur fin ou enter pour continuer ou terminer la saisie
+ Soit elle ne correspond pas et alors il faut effacer manuellement ce qu'on ne veut pas... Dans certains contextes c'est particulièrement pénible (téléphone tactile) et il y a dans tous les cas certaines personnes qui ne sont pas du tout à l'aise avec les concepts de sélection de texte (et à la souris on pert beaucoup de temps inutilement)

Google ne fait pas son autocompletion correctement. Je me retrouve très régulièrement avec des termes autocomplétés que je dois effacer manuellement, et qui ont en plus souvent absolument rien à voir avec ce que je veux vraiment rechercher.

ET qui de plus est, je suis un utilisateur de lecteur d'écran et le mode formulaire se désactive inopinément ! Je ne vais pas expliquer ce que ça signifie ici, mais si ça vous intrigue, n'hésitez pas à faire des recherches.


a écrit :
Pour info, j’ai réussi à simuler ce résultat avec une fonction JavaScript. Le problème c’est que le temps que la fonction s’exécute, le résultat met une demi-seconde à se réactualiser, et pendant ce temps le texte saisi passe par dessus le texte qui a le rôle de compléter la requête.

Pour ce problème-là, je suppose que tu fais une autre erreur de conception malheureusement récurrente.

En fait, il ne faut pas lancer l'autocompletion immédiatement après chaque frappe. C'est faux. Ca a effectivement de bonnes chances de produire ce que tu décris, à savoir que le texte autocomplété n'arrive pas au bon endroit ou se retrouve mélangé avec du texte saisi. D'autant plus si on sait ce qu'on veut et si on a une vitesse de frappe raisonnablement rapide.

La bonne façon de faire est d'attendre un petit peu avant de lancer la requête d'autocompletion via AJAX plutôt que de la lancer tout de suite après chaque frappe. A chaque nouvelle frappe, tu remets les compteurs à zéro et tu recommences à attendre. Si le délai que tu as fixé arrive à expiration sans qu'aucune nouvelle frappe n'ait lieu, alors tu lances ta requête.
Ceci se fait facilement avec setTimeout et clearTimeout, en vrai-faux-code de la façon suivante :

champ.onkeydown = function(){
if (timer!=null) clearTimeout(Timer);
timer = setTimeout(requeteAJAX, 500);
}
champ.onblur = function(){
if (timer!=null) clearTimeout(timer);
}


Pour faire encore mieux, on peut en bonus vérifier au moment où le résultat de la requête AJAX arrive que le texte dans le champ n'a pas changé.
Modifié par QuentinC (13 Jan 2014 - 19:16)