AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI Date de publication : 11 mars 2011 Dernière mise à jour :
L'autocomplétion, ou suggestion automatique, est l'un des moyens les plus intéressants pour faciliter le remplissage de formulaire. Je vous propose de mettre en place une autocomplétion visant à proposer le code postal et ville en fonction de la saisie de l'utilisateur. Pour faciliter le code JavaScript, nous utiliserons le Framework jQuery.
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
I - Introduction..............................................................................................................................................................3 II - La base de données.............................................................................................................................................. 3 III - Côté client............................................................................................................................................................. 4 IV - Côté serveur......................................................................................................................................................... 6 IV-A - ASP.NET C#................................................................................................................................................ 6 IV-B - PHP..............................................................................................................................................................7 V - Amélioration........................................................................................................................................................... 9 VI - Conclusion.......................................................................................................................................................... 10 VII - Remerciement....................................................................................................................................................10
-2Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
I - Introduction Les sites web évoluent avec le temps et deviennent de plus en plus sophistiqués. Le but principal des développeurs web est de simplifié et rendre plus agréable leurs utilisations. Nous allons mettre en place un système de proposition de code postal/ville dès la saisie de l'un de ces deux membres. Consulter la démo
II - La base de données Bien entendu nous n'allons pas saisir tous les codes postaux et les villes de France ! Nous avons à notre disposition une liste déjà toute faite sur le site ville de tous les pays.
http://www.geonames.org/. Il y a bien évidemment la liste des codes postaux/
Rendez-vous sur la page http://download.geonames.org/export/zip/ puis choisissez le pays que vous souhaitez. Pour ce tutoriel nous prendrons "FR.zip" Il se comporte de deux fichiers textes. Le premier est un fichier " lisez-moi " qui explique la licence du fichier des codes postaux, mais aussi la structure du fichier des codes postaux. Et le fameux fichier des codes postaux. Si vous ouvrez le fichier " FR.txt " vous constaterez que c'est une liste séparée par des tabulations, dont voici la structure : • • • • • • • • • •
Code ISO pays : 2 caractères Code postal : varchar(10) Ville : varchar(180) Nom région : varchar(100) Code région : varchar(20) Nom département : varchar(100) Code département : varchar(20) Nom communauté : varchar(100) Code communauté : varchar(20)
•
Longitude : longitude estimée ( wgs84) Précision : précision de la latitude et de la longitude, de 1 = estimé à 6 = centré
•
Latitude : latitude estimée (
wgs84)
On va donc créer une table correspondante à la structure de ce fichier. SQL version complète
CREATE TABLE IF NOT EXISTS `cp_autocomplete` ( `CODEPAYS` char(2) NOT NULL, `CP` varchar(10) NOT NULL, `VILLE` varchar(180) NOT NULL, `NOMADMIN1` varchar(100) NOT NULL, `CODEADMIN1` varchar(20) NOT NULL, `NOMADMIN2` varchar(100) NOT NULL, `CODEADMIN2` varchar(20) NOT NULL, `NOMADMIN3` varchar(100) NOT NULL, `CODEADMIN3` varchar(20) NOT NULL, `LATITUDE` double NOT NULL, `LONGITUDE` double NOT NULL, `ACURANCY` int(1) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Ou bien tout simplement une version plus légère contenant juste les informations dont nous avons besoin :
-3Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
SQL version légère
CREATE TABLE IF NOT EXISTS `cp_autocomplete` ( `CODEPAYS` char(2) NOT NULL, `CP` varchar(10) NOT NULL, `VILLE` varchar(180) NOT NULL, KEY `CODEPAYS` (`CODEPAYS`), KEY `CP` (`CP`), KEY `VILLE` (`VILLE`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Puis nous allons insérer les données, je vous épargne le travail de modification du fichier pour pouvoir l'importer dans votre SGBD, et je vous propose de télécharger le fichier SQL en légère. Pour la suite du tutoriel, j'utiliserai la version légère.
version complète ou en
version
III - Côté client On va donc créer une simple page HTML avec deux champs textes, un pour le code postal et l'autre pour la ville. HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>AutoCompletion</title> </head> <body> <form action="#"> CP :<input type="text" id="cp" size="6"/> Ville : <input type="text" id="ville" /> </form> </body> </html>
Puis nous allons y ajouter la librairie jQuery et jQuery UI. HTML
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script> <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.ui/1.8.10/jquery-ui.js"></ script>
Mais aussi le CSS pour jQuery UI HTML
<link rel="Stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/ themes/base/jquery-ui.css" />
Maintenant que notre structure est en place nous allons implémenter le code pour faire l'autocomplétion. Tout d'abord, nous déclarons notre autocomplétion sur les deux champs, avec les options de délai de 600milliseconde, pour éviter de trop surcharger notre serveur, mais aussi avec une longueur minimale de 3 caractères, pour les mêmes raisons que l'option précédente. JavaScript
$(function () { $("#cp, #ville").autocomplete({ source: function (request, response) { //TODO }, minLength: 3,
-4Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
JavaScript
delay: 600 }); });
En ce qui concerne la source, nous allons effectuer une requête Ajax vers notre serveur et il nous retournera un format de données JSON. On devra, au minimum, lui envoyé le début du code postal ou de la ville, mais je vais ajouter le code pays et le nombre maximum de valeurs à retourner. JavaScript
var objData = {}; if ($(this.element).attr('id') == 'cp') { objData = { codePostal: request.term, pays: 'FR', maxRows: 10 }; } else { objData = { ville: request.term, pays: 'FR', maxRows: 10 }; }
Pour fonctionner, l'autocomplétion de jQuery a besoin d'un tableau d'objet sous le format suivant : [{label :'�', value :'�'},{�}] où label correspond à la valeur qui sera affichée dans la liste des propositions et value à la valeur qu'il y aura dans le champ une fois la ligne sélectionnée. On va donc devoir construire ce tableau à partir des données JSON reçu depuis le serveur. JavaScript
$.ajax({ url: "./AutoCompletion.php", dataType: "json", data: objData, type: 'POST', success: function (data) { response($.map(data, function (item) { return { label: item.CodePostal + ", " + item.Ville, value: function () { if ($(this).attr('id') == 'cp') { $('#ville').val(item.Ville); return item.CodePostal; } else { $('#cp').val(item.CodePostal); return item.Ville; } } } }));
} });
Vous pouvez dès à présent essayer de saisir une valeur dans l'un des deux champs et vous observerez, avec firebug par exemple, qu'une requête Ajax est envoyée sur la page AutoCompletion.php avec les paramètres POST suivant : codePostal, maxRows et pays.
-5Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
IV - Côté serveur Il faut maintenant faire le côté serveur, je vous propose donc de le faire dans deux langages différents. Le principe est quasiment pareil, choisissez celui que vous voulez.
IV-A - ASP.NET C# Nous allons commencer par créer une classe que l'on nommera AutoCompletionCPVille et qui sera constituée de deux propriétés le code postal (string) et la ville (string), ainsi que son constructeur. C#
public class AutoCompletionCPVille { private string codePostal; private string ville; {
public AutoCompletionCPVille(string p_codePostal, string p_ville) codePostal = p_codePostal; ville = p_ville;
}
public string CodePostal { get { return codePostal; } set { codePostal = value; } } public string Ville { get { return ville; } set { ville = value; } }
}
Ensuite, nous allons instancier une liste vide de la classe AutoCompletionCPVille. Cette liste sera remplie par la base de données puis elle sera convertie en JSON. Il faut ensuite construire la requête SQL en fonction de ce que l'on veut chercher, code postal ou ville. Il nous reste plus qu'à boucler sur nos résultats afin d'instancier un objet de la classe AutoCompletionCPVille, puis d'insérer cet objet dans notre liste. Pour transformer notre liste d'objet de type AutoCompletionCPVille, nous allons utiliser la classe JavaScriptSerializer, présence depuis la version 3.5 du Framework .NET. Cette classe contient la méthode Serialize() qui prendra en paramètre notre liste et nous retournera une chaine de caractère correspondante au format JSON de notre liste. C#
using using using using using
System; System.Configuration; System.Collections.Generic; System.Web.Script.Serialization; MySql.Data.MySqlClient;
public partial class client_AutoCompletion : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Initialisation de la liste List<AutoCompletionCPVille> list = new List<AutoCompletionCPVille>(); //Connexion MySQL MySqlConnection connexion = new MySqlConnection(ConfigurationManager.ConnectionStrings["batifacConnectionMySql"].ConnectionString); connexion.Open();
-6Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
C#
//Construction de la requete string strQuery = "SELECT CP, VILLE FROM autocomplete WHERE "; if (Request.Form["codePostal"] != null) { strQuery += "CP LIKE ?codePostal "; } else { strQuery += "VILLE LIKE ?ville "; } strQuery += "AND CODEPAYS = 'FR' "; //Limite if (Request.Form["maxRows"] != null) { strQuery += "LIMIT 0 , ?maxRows"; } MySqlCommand query = new MySqlCommand(strQuery, connexion); if (Request.Form["codePostal"] != null) { query.Parameters.AddWithValue("?codePostal", Request.Form["codePostal"] + "%"); } else if (Request.Form["ville"] != null) { query.Parameters.AddWithValue("?ville", Request.Form["ville"] + "%"); } //Limite if (Request.Form["maxRows"] != null) { query.Parameters.AddWithValue("?maxRows", int.Parse(Request.Form["maxRows"])); } MySqlDataReader data = query.ExecuteReader(); while (data.Read()) { list.Add(new AutoCompletionCPVille(data.GetString("CP"), data.GetString("VILLE"))); } //Fermeture du curseur data.Close(); //Fermeture de la connexion connexion.Close();
}
}
JavaScriptSerializer oSerializer = new JavaScriptSerializer(); string strJSON = oSerializer.Serialize(list); Response.Write(strJSON);
IV-B - PHP Nous allons commencer par créer une classe que l'on nommera AutoCompletionCPVille et qui sera constituée de deux propriétés le code postal et la ville, ainsi que son constructeur. Les propriétés doivent avoir la visibilité public pour qu'elle puisse entre lu par la méthode de transformation en JSON. PHP
<?php class AutoCompletionCPVille { public $CodePostal; public $Ville; } ?>
Ensuite, nous allons instancier un tableau vide. Ce tableau sera rempli par la base de données puis il sera converti en JSON. Il faut ensuite construire la requête SQL en fonction de ce que l'on veut chercher, code postal ou ville. Ensuite
-7Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
nous utiliserons la méthode fetchAll() avec les paramètres PDO::FETCH_CLASS et "AutoCompletionCPVille" pour insérer tous les résultats dans un tableau en gardant la structure de la classe AutoCompletionCPVille. Pour transformer notre tableau d'objet de type AutoCompletionCPVille, nous allons utiliser la fonction json_encode, présence depuis la version 5.2 de PHP. Cette fonction nous retournera une chaine de caractère correspondante au format JSON de notre tableau. PHP
<?php require_once('./AutoCompletionCPVille.class.php'); //Initialisation de la liste $list = array(); //Connexion MySQL try { $db = new PDO('mysql:host=localhost;dbname=bdname', 'root', 'root'); } catch (Exception $ex) { echo $ex->getMessage(); } //Construction de la requete $strQuery = "SELECT CP CodePostal, VILLE Ville FROM autocomplete WHERE "; if (isset($_POST["codePostal"])) { $strQuery .= "CP LIKE :codePostal "; } else { $strQuery .= "VILLE LIKE :ville "; } $strQuery .= "AND CODEPAYS = 'FR' "; //Limite if (isset($_POST["maxRows"])) { $strQuery .= "LIMIT 0, :maxRows"; } $query = $db->prepare($strQuery); if (isset($_POST["codePostal"])) { $value = $_POST["codePostal"]."%"; $query->bindParam(":codePostal", $value, PDO::PARAM_STR); } else { $value = $_POST["ville"]."%"; $query->bindParam(":ville", $value, PDO::PARAM_STR); } //Limite if (isset($_POST["maxRows"])) { $valueRows = intval($_POST["maxRows"]); $query->bindParam(":maxRows", $valueRows, PDO::PARAM_INT); } $query->execute(); $list = $query->fetchAll(PDO::FETCH_CLASS, "AutoCompletionCPVille");; echo json_encode($list); ?>
-8Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
V - Amélioration Nous allons à présent procéder à une amélioration non vitale au fonctionnement, mais forte intéressante en matière de ressource serveur. Nous allons mettre en cache, coté client, les réponses des requêtes Ajax effectuées, pour qui si l'utilisateur venait à taper deux fois la même requête nous ne ferions pas une requête Ajax, mais nous utiliserons le cache. Pour cela rien de bien compliquer, il faut créer une variable que l'on nommera cache. Puis à chaque succès d'une requête Ajax, nous ajouterons dans notre variable, en clé la requête saisie et en valeur la valeur JSON de retour. Ensuite à chaque requête, nous regarderons s'il la requête saisie existe en clé de notre variable cache grâce au mot clé in. Si c'est le cas alors nous utiliserons la valeur du cache pour construire le tableau d'objet pour le plugin d'autocomplétion. Et si elle n'est pas présente, nous ferons tout simplement la requête Ajax habituelle, qui je le rappelle sera enregistrée dans la variable cache. JavaScript
var cache = {}; $(function () { $("#cp, #ville").autocomplete({ source: function (request, response) { //Si la réponse est dans le cache if (('FR' + '-' + request.term) in cache) { response($.map(cache['FR' + '-' + request.term], function (item) { return { label: item.CodePostal + ", " + item.Ville, value: function () { if ($(this).attr('id') == 'cp') { $('#ville').val(item.Ville); return item.CodePostal; } else { $('#cp').val(item.CodePostal); return item.Ville; } } } }));
} //Sinon -> Requete Ajax else { var objData = {}; if ($(this.element).attr('id') == 'cp') { objData = { codePostal: request.term, pays: 'FR', maxRows: 10 }; } else { objData = { ville: request.term, pays: 'FR', maxRows: 10 }; } $.ajax({ url: "./AutoCompletion.php", dataType: "json", data: objData, type: 'POST', success: function (data) { //Ajout de reponse dans le cache -9Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/
AutoComplétion Code Postal/Ville avec jQuery par Xavier ZOLEZZI
JavaScript
cache[('FR' + '-' + request.term)] = data; response($.map(data, function (item) {
return { label: item.CodePostal + ", " + item.Ville, value: function () { if ($(this).attr('id') == 'cp') { $('#ville').val(item.Ville); return item.CodePostal; } else { $('#cp').val(item.CodePostal); return item.Ville; } } } })); } });
} }, minLength: 3, delay: 600 }); });
VI - Conclusion Voilà notre système d'autocomplétion est maintenant en place, vous pouvez bien entendu l'améliorer ou bien y rajouter des fonctionnalités, notamment la gestion de différent pays. On voit ici toute la puissance et l'intérêt de l'utilisation d'un Framework Javascript. Pour les personnes qui n'ont pas réussi à faire fonctionner leur système en suivant ce tutoriel, je vous mets à disposition les fichiers sources complets. Autocomplétion PHP - MySQL Autocomplétion PHP - SQLite Autocomplétion ASP.NET C# - MySQL
VII - Remerciement Je tiens particulièrement à remercier **** pour sa relecture attentive.
- 10 Copyright © 2011 - Xavier ZOLEZZI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://x-zolezzi.developpez.com/tutoriels/web/autocompletion/