Tutorial : suggestions (auto-completion) en Ajax avec JQuery et Php

Pour ce deuxième tutoriel sur l’ajax, je te propose un formulaire avec auto-complétion. Simplement afficher des suggestions quand l’utilisateur commence à taper dans un champ de texte. Les suggestions sont affichées grâce à Ajax qui permet d’effectuer des requêtes SQL en « arrière-plan » de la page. Toute la partie JavaScript sera faite grâce au framework JQuery.

auto-completion avec Ajax et Jquery

Comme d’hab, j’ai préparé une page de démo du script : disponible ici. Et il est également possible de télécharger les fichiers sources de cette démo. Et bien sûr, tout le code présenté ici est dépouillé de toute mise en forme (libre à toi de le personnaliser après !).

Jquery : auto-complétion

Donc, pour commencer, on va préparer le code HTML nécessaire : le champ de texte sur lequel les suggestions vont être appliqué et le bloc (caché au début de la page) qui va éventuellement contenir les suggestions :

1
2
3
4
5
6
7
8
9
10
11
12
<div>
		Rechercher un pays :
		<br />
		<input type="text" size="30" value="" id="inputString" /><!--  champ texte à analyser pour les suggestions -->
</div>
 
<div class="suggestionsBox" id="suggestions" style="display: none;"> <!-- bloc contenant les eventuelles suggestions -->
		<img src="upArrow.png" style="position: relative; top: -12px; left: 30px;" alt="upArrow" /> <!-- image de la fleche vers le haut -->
		<div class="suggestionList" id="autoSuggestionsList"><!-- liste contenant les suggestions -->
			&nbsp;
		</div>
</div>

Ensuite, dans le code javascript, on retrouve les deux fonctions nécessaires : lookup qui permet de faire l’appel ajax et fill qui permet, comme son nom l’indique, de remplir le champ avec la valeur suggerée. Après avoir défini les deux fonctions, on ajoute les « écouteurs » (qui permettent de surveiller si un événement est effectué) avec keyup (quand on appuie sur le clavier, à la remontée de la touche) et blur (quand le champ texte perd le focus).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function lookup(inputString) {
		if(inputString.length == 0) { // si le champs txte est vide
			$('#suggestions').hide(); // on cache les suggestions
		} else { // sinon
			$.post("ajax.php", {queryString: ""+inputString+""}, function(data){ // on envoit la valeur du champ texte dans la variable post queryString au fichier ajax.php
				if(data.length >0) {
					$('#suggestions').show(); // si il y a un retour, on affiche la liste
					$('#autoSuggestionsList').html(data); // et on remplit la liste des données
				}
			});
		}
}
 
function fill(thisValue) { // remplir le champ texte si une suggestion est cliquée
	$('#inputString').val(thisValue);
	setTimeout("$('#suggestions').hide();", 200);
}
 
$(document).ready( function () { // lorsque la page est entierement chargée
	$("input#inputString").keyup( function() { // si on presse une touche du clavier en étant dans le champ texte qui a pour id inputString
		lookup($(this).val()) 
	});
 
	$("input#inputString").blur( function() { // si le champs texte perd le focus
		fill() 
	});
});

Enfin, il ne reste plus qu’à développer le php qui sera exécuté grâce à l’appel ajax. Dans ce script, on  récupère la valeur passée (ce qui est saisi dans le champ texte) et il n’y a plus qu’à faire une requête SQL dans la base de données et d’afficher les résultats sous forme de liste (avec en prime un petit onClick=fill() sur chaque élément de liste permettant de remplir le champ texte.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
< ?php	
 
	$link = mysql_connect("hote de la base", "login", "pass") or die("Impossible de se connecter : " . mysql_error());
	mysql_select_db("db278690514");
 
		// si une variable queryString a été posté
               if(isset($_POST['queryString'])) {
 
			// si la longueur du contenu de la variable est superieur à 0			
			if(strlen($queryString) >0) {
 
				// requete sql à personnaliser pour correspondre à votre base de données
				$result = mysql_query("SELECT value FROM countries WHERE value LIKE '$queryString%' LIMIT 10");
				if($result) {
 
					// on parcourt les resultats
					while ($pays = mysql_fetch_object($result)) {
						// on affiche les resultats dans un element de liste en ajoutant 
                                                // la fonction fill sur l'evenenement onClick
		         			echo '<li onClick="fill(\''.$pays->value.'\');">'.$pays->value.'</li>';
	         		        }
				} else {
					echo 'Il y a une probleme avec la requete sql.';
				}
			} 
		} else {
			echo 'Il ne devrait pas avoir un accès direct à ce script !!!';
		}
?>

Tutoriel basé sur celui du blog nodstrum : http://nodstrum.com/2007/09/19/autocompleter/

Ce contenu a été publié dans JQuery, PHP, avec comme mot(s)-clé(s) , , , , . Vous pouvez le mettre en favoris avec ce permalien.

28 reponses a Tutorial : suggestions (auto-complétion) en Ajax avec JQuery et Php

  1. Bernard dit :

    Bonjour,

    Oui très bien et cela permet d’éviter d’utiliser la classe mysqli comme dans le lien cité au dessus.
    Par contre une petite coquille me semble t’il dans le code php.
    Si l’on fait un strlen sur une variable non déclarée ça ne marche pas, j’ai donc rajouté en ligne 9:$queryString=$_POST[‘queryString’];

    et également pour les accents et le simple quote: en ligne 20
    echo ‘value)).’\’); »>’.addslashes(utf8_encode($pays->value)). »;

  2. Arnaud dit :

    Bonjour

    Merci pour cette astuce.

    Une remarque toutefois : cette astuce ne permet de sélectionner les propositions qu’avec la souris ( et pas le clavier, sob…)

    Or lorsque qu’on laisse ce code dans le script JS

    $(« input#inputString »).blur( function() { // si le champs texte perd le focus
    fill()
    });

    on enlève bien la liste lorsque l’on perd le focus. Comme indiqué dans le commentaire.

    Le problème c’est que quand on veut séléctionner une proposition (avec la souris donc), on perd le focus sur le champ de saisi et donc on ne séléctionne rien…

    La seul solution que j’ai trouvé pour l’instant c’est d’enlever ces lignes.

    Voilà

    Bonne journée

  3. manu63 dit :

    Bonjour,

    J’ai réussi a adapter ce code mais j’aimerai aller plus loin en affichant les information de la bdd mysql par rapport au pays séléctionné.
    Je m’explique : si je séléctionne Albanie, ça m’affiche dans une div les infos concernant le pays, ça ne marche pas pour l’instant, voici mon code :

    fichier afficher_pays.php :

    0) {

    $query = « SELECT CD.nom, CD.superficie, CD.population, CD.monnaie, CD.hymne
    FROM countries_desc CD, countries CO
    WHERE CD.id_c = CO.id_c AND CO.value = ‘$queryString' »;

    $result = mysql_query($query);
    if($query)
    {
    while ($row = mysql_fetch_array($result))
    {?>

    Nom
    Superficie
    Population
    Monnaie
    Hymne

    fichier rechercher.js :

    $(document).ready(function(){

    $(« #Envoyer »).click(function(){
    var queryString = $(‘#inputString’).val();
    var dataString = ‘resultats=’+queryString;
    $.ajax({
    type: »POST »,
    url: »contenu/afficher_pays.php »,
    data:{table:queryString},
    cache:false,
    beforeSend:function(html){
    $(‘#resultats’).show();
    $(‘#resultats’).html(queryString);
    },
    success:function(html){
    $(‘#resultats’).show();
    $(‘#resultats’).append(html);
    }

    });

    return false;
    });

    });

    function lookup(inputString) {
    if(inputString.length == 0) {
    // Hide the suggestion box.
    $(‘#suggestions’).hide();
    } else {
    $.post(« contenu/rpc.php », {queryString: «  »+inputString+ » »}, function(data){
    if(data.length >0) {
    $(‘#suggestions’).show();
    $(‘#autoSuggestionsList’).html(data);
    }
    });
    }
    } // lookup

    function fill(thisValue) {
    $(‘#inputString’).val(thisValue);
    setTimeout(« $(‘#suggestions’).hide(); », 200);
    }

    function afficher(data){
    $(‘#resultats’).show(function(){
    $(‘#resultats’).empty();
    $(‘#resultats’).append(data);
    });
    }

    fichier index.php :

    Ajax Autocompletion

    Rechercher un pays: 

     

    Merci d’avance pr vos aides

  4. Antoine dit :

    Cool ce tuto, le rendu semble vraiment bien et complet.
    Cependant le script (meme de démo) ne fonctionne pas chez moi(ni sous la dernière version de firefox ni sous IE 7). Est-ce normal?

    Merci

  5. Tomtom dit :

    Hello !

    Je trouve cet exemple vraiment super !
    Par contre, est ce que quelqu’un aurait une idée pour naviguer dans le menu avec le clavier (touche haut et bas) et dans l’idéal pour pouvoir sélectionner une suggestion avec la touche Entrer.

    J’ai regardé sur le site de nodstrum, personne n’a réussi a réussie à trouver un moyen de le faire.

    Merci !

  6. Cold FuZion dit :

    Sympa comme tout ce tuto , mais évites de mettre tes identifiants dans le fichier source .zip . 😉

  7. Sylvain dit :

    Je ne comprend pas,
    même si je fais un copier/coller de tous ca, ca ne fonctionne pas chez moi. Même le lien de demo ne donne aucun resultat, ni sur firefox, ni sur IE ! (pourtant, un alert(ville.length); dans le .js me prouve qu’il est bien lu par mon navigateur)

    Avant de tomber sur ce script, j’ai moi mm programmé 1 truc assez similaire ; et je suis résté bloqué sur $(‘#suggestions’).show() qui ne donne aucun resultat.

  8. Cold FuZion dit :

    @Sylvain , après if(isset($_POST[‘queryString’])) {
    ajoutes : $queryString = $_POST[‘queryString’];

    ça devrait déjà résoudre une erreur.

  9. Sylvain dit :

    Merci Cold FuZion. Effectivement, ça + qques autres trucs dont vous avez deja parlé, et ça marche ! (j’aurais dû lire + en detail vos commentaires, tout y est).

    Par contre, une question me turlupine : est il possible d’afficher les resultats non plus dans une div, mais directement dans un . Ce qui me permetrait de ne pas avoir a mettre une image upArrow.png, et d’avoir un style css de liste identique aux autres listes de ma page + gestion du select realisée directement par le navigateur client (et pas par javascript), etc.

    Je creuse dans ce sens, ou c’est impossible/inutile ??

  10. Sylvain dit :

    Merci Cold FuZion. Effectivement, ça + qques autres trucs dont vous avez deja parlé, et ça marche ! (j’aurais dû lire + en detail vos commentaires, tout y est).

    Par contre, une question me turlupine : est il possible d’afficher les resultats non plus dans une div, mais directement dans un select . Ce qui me permetrait de ne pas avoir a mettre une image upArrow.png, et d’avoir un style css de liste identique aux autres listes de ma page + gestion du select realisée directement par le navigateur client (et pas par javascript), etc.

    Je creuse dans ce sens, ou c’est impossible/inutile ??

  11. teoz dit :

    C’est moi ou la démo ne fonctionne pas ?

  12. Cold FuZion dit :

    La démo marche pas 😉

  13. smith dit :

    Bonjour,

    J’ai un pb et je voudrais bien avoir de l’aide : Je crée un tableau avec des onglets dynamiquement. ensuite je charge le contenu des ces onglets dynamiquement quand je clique l’onglet. le contenu c’est un formulaire. je soumet un certain nombre des requêtes et j’affiche le résultats sur la même page. Je voudrais faire de la pagination sur les résultats trouvés, donc, je n’affiche que 2 résultats par exemple et un bouton suiv doit m’afficher la 3eme page; quand je clique sur suiv, la page est recharger sur le premier onglet de la page et non sur l’onglet où je vais qu’elle s’affiche. je ne comprends pas pourquoi.

  14. smith dit :

    voici le codes ajax : $(‘#tabderesultat a’).click( function(e) {
    e.preventDefault(); // on empeche l’envoi du formulaire par le navigateur
    var pageNum = (this).id ;
    var num = ;
    $.ajax({
    type: ‘POST’, // envoi des données en POST
    url: « sphinx_htdocs_test.php?Numpage= »+pageNum+ « &res=&num= », // envoi au fichier défini dans l’attribut action
    data: pageNum, // sélection des champs à envoyer
    success: function(msg) { // callback en cas de succès
    $(« #contenu »).replaceWith(msg);
    }
    });
    return false;

    });

  15. bulldog dit :

    Merci pour ce super tuto. :))

    Maintenant si l’on souhaite ajouter la capitale relative au pays. Comment faire?

    Merci par avance

  16. bulldog dit :

    Re,

    Le souci est le suivant, je souhaiterai afficher la ville, le département et la région dans la même « bulle ».

    J’ai 3 tables:
    departement -> id_departement / id_region/ code/ nom_departement
    region -> id_region / nom_region
    maps_ville -> id_ville / id_departement/nom/cp

    Mon code de traitement php:

    0) {

    $result = mysql_query("SELECT * FROM maps_ville, departement, region WHERE nom LIKE '$queryString%' AND id_depart=nom_departement AND id_region = nom_region LIMIT 10");

    if($result) {

    while ($recherche = mysql_fetch_object($result)) {

    echo 'nom&$recherche->nom_departement&$recherche->nom_region.'\');">'.addslashes(utf8_encode($recherche->ville)).','.$recherche->nom_departement.','.$recherche->nom_region.'';
    }

    }
    }
    }
    ?>

    Merci d’avance pour votre aide

  17. Benji dit :

    Bonjour !
    je suis débutant et j’ai voulu essayer d’adapter pour faire 4 zone de saisie. Le problème est qu’il complète seulement une zone sur les 4 zone.
    Pouvez vous m’aidez ?
    Merci !

  18. Julien dit :

    Salut Benji ! Moi aussi je suis débutant en JQuery et pourtant je suis parvenue assez vite à l’implémenter dans un projet sur plusieurs champs ! Il faut surtout que tu change le nom de tes variables dans tes scripts et tes champs sinon tu auras un conflit !
    Si j’ai pu t’aider ne serait-ce qu’un peu …
    Sinon merci à Arnaud pour ce blog que j’ai découvert depuis peu et je suis déjà fan! Merci pour les tuto’s et sources que tu trouves!

  19. mathieu dit :

    pour une petite démonstration en ligne de « gcomplete » :

    http://mdormeval44.free.fr/demos/002-autocompletion-avec-jquery.html

  20. geeky dit :

    Bonjour,
    Tt d’abord merci beaucoup pour cette démo.

    J’ai un problème dans le script.
    J’ai bien rajouté la variable manquante ($queryString=$_POST[‘queryString’];) mais il m’apparaît tjs une erreur : undefined property stdClass::$value on line 19

    Quelqu’un peut il me dire quel ligne je fois mettre à la place de la 19 ?
    Merci

  21. tony dit :

    Bonjour j’ai tester votre script et j’ai essayer de le faire fonctionner mais dès que je tape quelque chose j’ai le retour  » ‘Il y a un probleme avec la requete sql  » j’ai pourtant adopté :

    $result = mysql_query(« SELECT value FROM test WHERE value LIKE ‘$queryString%’ LIMIT 10 »);

    faut t’il un définir un paramétré spécial dans pour le champ SQL

  22. Whoa dit :

    Bonjour.
    Merci pour ce script, j’ai ajouté un enregistrement dans la base de données qui comporte une apostrophe ; et dans ce cas, la valeur ne rentre pas dans l’input.
    Autre chose, la navigation avec les fléches du clavier ne fonctionne pas :

  23. Leon dit :

    Bonjour,
    J’ai adapté votre très bon tuto mais je n’arrive pas à récupérer la valeur (comme un $_POST[‘nom’];) afin de l’utiliser dans une autre page.
    Merci de votre aide.

  24. bennn dit :

    s’il vous plais comment pproceder pour utiliser votre codes source en joomla sachant que chaque ficheier doit etre saisi dans un article joomla mais je comprend pas comment appeler le fichier ajax.php.mercii

  25. bakus dit :

    Escapade vers les fans de ASP.NET
    Sur la Webform, un bout d’ajax
    ***********************************************
    function serviceCall(aaa) {

    if (aaa.length == 0) {
    // Hide the suggestion box.
    $(‘#suggestions’).hide();

    }
    else {
    $.ajax({
    type: « POST »,
    url: ‘WebServiceCall.asmx/GetDataSuggestion’,
    data: « {‘xbox’:' » + aaa + « ‘} »,
    contentType: « application/json; charset=utf-8 »,
    dataType: « json »,
    success: function (msg) {
    var data = «  »;
    var k = msg.d.length;
    for (var i = 0; i 0) {
    $(‘#suggestions’).show();
    $(‘#autoSuggestionsList’).html(data);
    }
    },
    error: function (e) {
    alert(« Error »);
    }
    });
    }
    }
    function fill(thisValue) {
    $(‘#inputString’).val(thisValue);
    $(‘#gaga’).val(thisValue);
    setTimeout(« $(‘#suggestions’).hide(); », 200);
    }
    //
    //

    Saisir le Nom :

     

    ***********************************
    qui consome le service web (asmx) suivant :
    *******************************************
    [WebService(Namespace = « http://tempuri.org/ »)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class WebServiceCall : System.Web.Services.WebService
    {

    [WebMethod(EnableSession = true)]
    public List GetDataSuggestion(string xbox)
    {
    List ret = new List();
    //ret.Add(«  »);
    using (CalldbEntities db = new CalldbEntities())
    {
    //var zut = (from c in db.Subscribers
    // where c.Name.Contains(xbox)
    // select new { c.Name, c.Mobile }).Take(10);
    var zut = db.Subscribers.Where(x => x.Name.Contains(xbox)).Take(10).Select(c=>new{c.Name,c.Mobile});
    if (zut != null)
    {
    foreach (var d in zut)
    {
    ret.Add(«  » +d.Name + «  »);
    }
    }
    else
    {
    ret.Add( » Pas des données »);
    }
    }
    //ret.Add(«  »);
    return ret;
    }
    }

    ******************************************
    C’est pratique !!!!!!

  26. SimonBHB dit :

    Bonjours,
    j’aimerais savoir si comment modifier le code js pour que quand on tape un mot et qu’on le sélectionne: qu’il soit bien placé dans l’input et que sont id soit mit dans un input hidden ? Ca me serait très utile.
    Cordialement

  27. Atef dit :

    Merci bcp pour ce démo ! C’est un très bon tuto *_* !
    Bon courage 🙂

  28. Sipherion dit :

    Bonjour,

    Le site de démonstration de ce tutoriel a une erreur Javascript (illegal character) donc impossible d’avoir une démo fonctionnelle.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *