[RESOLU] Autocompletion sur Pays, ville, région et départment

Eléphant du PHP | 115 Messages

22 août 2017, 10:09

Bonjour tous le monde,

Depuis quelques jours je cherche a réaliser un formulaire, avec la possibilité de remplier des champs en automatique avec deux champ remplie.

mon but est le suivant :

Je voudrais remplir le pays, puis le code postal, et là il me donne un choix de ville que je choisie puis il remplir la région puis le département en auto.

Voilà le code que j’utilise :

AutoCompletion.php :

Code : Tout sélectionner

<?php require_once('./AutoCompletionCPVille.class.php'); //Initialisation de la liste $list = array(); //Connexion MySQL try { $db = new PDO('mysql:host=123.123.123.123;dbname=pays', 'root', 'root', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); } catch (Exception $ex) { echo $ex->getMessage(); } //Construction de la requete $strQuery = "SELECT CP CodePostal, VILLE Ville FROM pays 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); ?>
AutoCompletionCPVille.class.php :

Code : Tout sélectionner

<?php class AutoCompletionCPVille { public $CodePostal; public $Ville; } ?>
index.php :

Code : Tout sélectionner

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>AutoCompletion</title> <script type="text/javascript" src="https://code.jquery.com/jquery-1.5.1.min.js"></script> <script type="text/javascript" src="https://ajax.microsoft.com/ajax/jquery.ui/1.8.10/jquery-ui.js"></script> <script type="text/javascript"> var cache = {}; $(function () { $("#cp, #ville, #region").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 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 }); }); </script> <link rel="Stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" /> </head> <body> <form action="#"> Pays :<input type="text" id="ps" size="6"/> Code postal :<input type="text" id="cp" size="6"/> Ville : <input type="text" id="ville" /> Région : <input type="text" id="rg" /> Département : <input type="text" id="dp" /> </form> </body> </html>
autocomplete.sql :

Code : Tout sélectionner

-- phpMyAdmin SQL Dump -- version 3.3.7 -- http://www.phpmyadmin.net -- -- Serveur: localhost -- Généré le : Mer 09 Mars 2011 à 16:24 -- Version du serveur: 5.1.51 -- Version de PHP: 5.2.14 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -- -- Base de données: `batifac` -- -- -------------------------------------------------------- -- -- Structure de la table `pays` -- CREATE TABLE IF NOT EXISTS `pays` ( `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; -- -- Contenu de la table `pays` -- INSERT INTO `pays` (`CODEPAYS`, `CP`, `VILLE`) VALUES ('FR', '24000', 'Périgueux'), ('FR', '24001', 'Périgueux'), ('FR', '24002', 'Périgueux'), ('FR', '24003', 'Périgueux'), ('FR', '24004', 'Périgueux'), ('FR', '24005', 'Périgueux'), ('FR', '24007', 'Périgueux'), ('FR', '24009', 'Périgueux'), ('FR', '24010', 'Périgueux'), ('FR', '24011', 'Périgueux'), ('FR', '24012', 'Périgueux'), ('FR', '24013', 'Périgueux'), ('FR', '24014', 'Périgueux'), ('FR', '24015', 'Périgueux'), ('FR', '24016', 'Périgueux'), ('FR', '24017', 'Périgueux'), ('FR', '24019', 'Périgueux'), ('FR', '24020', 'Périgueux'), ('FR', '24022', 'Périgueux'), ('FR', '24024', 'Périgueux'), ('FR', '24029', 'Périgueux'), ('FR', '24050', 'Périgueux'), ('FR', '24051', 'Périgueux'), ('FR', '24052', 'Périgueux'), ('FR', '24055', 'Périgueux'), ('FR', '24059', 'Périgueux'), ('FR', '24060', 'Périgueux'), ('FR', '24100', 'Creysse'), ('FR', '24100', 'Bergerac'), ('FR', '24100', 'Lembras'), ('FR', '24100', 'Saint-Laurent-des-Vignes'), ('FR', '24101', 'Bergerac'), ('FR', '24102', 'Bergerac'), ('FR', '24104', 'Bergerac'), ('FR', '24105', 'Bergerac'), ('FR', '24106', 'Bergerac'), ('FR', '24107', 'Bergerac'), ('FR', '24108', 'Bergerac'), ('FR', '24109', 'Bergerac'), ('FR', '24110', 'Saint-Astier'), ('FR', '24110', 'Montrem'), ('FR', '24110', 'Léguillac-de-l''Auche'), ('FR', '24110', 'Grignols'), ('FR', '24110', 'Manzac-sur-Vern'), ('FR', '24110', 'Saint-Aquilin'), ('FR', '24110', 'Bourrou'), ('FR', '24110', 'Saint-Léon-sur-l''Isle'), ('FR', '24111', 'Bergerac'), ('FR', '24112', 'Bergerac'), ('FR', '24113', 'Bergerac'), ('FR', '24114', 'Bergerac'), ('FR', '24120', 'La Feuillade'), ('FR', '24120', 'La Dornac'), ('FR', '24120', 'Terrasson-Lavilledieu'), ('FR', '24120', 'La Cassagne'), ('FR', '24120', 'Chavagnac'), ('FR', '24120', 'Villac'), ('FR', '24120', 'Grèzes'), ('FR', '24120', 'Châtres'), ('FR', '24120', 'Beauregard-de-Terrasson'), ('FR', '24120', 'Coly'), ('FR', '24120', 'Pazayac'), ('FR', '24121', 'Terrasson-Lavilledieu'), ('FR', '24122', 'Terrasson-Lavilledieu'), ('FR', '24130', 'Saint-Pierre-d''Eyraud'), ('FR', '24130', 'Ginestet'), ('FR', '24130', 'Le Fleix'), ('FR', '24130', 'Saint-Georges-Blancaneix'), ('FR', '24130', 'La Force'), ('FR', '24130', 'Monfaucon'), ('FR', '24130', 'Lunas'), ('FR', '24130', 'Prigonrieux'), ('FR', '24130', 'Bosset'), ('FR', '24130', 'Laveyssière'), ('FR', '24130', 'Fraisse'), ('FR', '24140', 'Saint-Hilaire-d''Estissac'), ('FR', '24140', 'Beauregard-et-Bassac'), ('FR', '24140', 'Jaure'), ('FR', '24140', 'Beleymas'), ('FR', '24140', 'Saint-Julien-de-Crempse'), ('FR', '24140', 'Saint-Martin-des-Combes'), ('FR', '24140', 'Clermont-de-Beauregard'), ('FR', '24140', 'Villamblard'), ('FR', '24140', 'Maurens'), ('FR', '24140', 'Saint-Jean-d''Eyraud'), ('FR', '24140', 'Saint-Jean-d''Estissac'), ('FR', '24140', 'Saint-Georges-de-Montclard'), ('FR', '24140', 'Douville'), ('FR', '24140', 'Montagnac-la-Crempse'), ('FR', '24140', 'Campsegret'), ('FR', '24140', 'Queyssac'), ('FR', '24150', 'Saint-Capraise-de-Lalinde'), ('FR', '24150', 'Badefols-sur-Dordogne'), ('FR', '24150', 'Bourniquel'), ('FR', '24150', 'Lanquais'), ('FR', '24150', 'Baneuil'), ('FR', '24150', 'Varennes'), ...
Voilà si cela peut aider d'autre personne j'ai mis tous le code.

Merci de votre aide,

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

22 août 2017, 11:19

Ce qui se fait de plus en plus, c'est des autocomplétion sur l'adresse complète (à voir si c'est pertinent dans ton cas car si tu n'as besoin que de la ville c'est pas adapté).
Quelques exemples :
https://community.algolia.com/places/
https://developers.google.com/maps/docu ... form?hl=fr
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 115 Messages

22 août 2017, 12:39

Merci de ton aide @rthur,

J'avance bien mais j'ai une question j'ai choisie cela "https://community.algolia.com/places/"
je n'arrive pas a avoir le Département et les recherche que sur la France voilà mon code :

Code : Tout sélectionner

<form action="/billing" class="form"> <div class="form-group"> <label for="form-city">City*</label> <input type="text" class="form-control" id="form-city" placeholder="City"> <label for="form-zip">ZIP code*</label> <input type="text" class="form-control" id="form-zip" placeholder="ZIP code"> </div> <div class="form-group"> <label for="form-address2">Région</label> <input type="text" class="form-control" id="form-region" placeholder="Street number and name" /> </div> <div class="form-group"> <label for="form-address2">Département</label> <input type="text" class="form-control" id="form-departement" placeholder="Région" /> </div> </form> <div class="form-group"> <label for="form-country">Country</label> <input type="text" class="form-control" id="country" placeholder="Pays" /> </div> </form> <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> <?php $appId = 'xxxx'; $apiKey = 'xxxx'; //$places = \AlgoliaSearch\Client::initPlaces($appId, $apiKey); //$result = $places->search(''); //var_dump($result); ?> <script> (function() { var placesAutocomplete = places({ container: document.querySelector('#form-city'), type: 'city', templates: { value: function(suggestion) { return suggestion.name; } } }); placesAutocomplete.on('change', function resultSelected(e) { document.querySelector('#form-zip').value = e.suggestion.postcode || ''; document.querySelector('#form-region').value = e.suggestion.administrative || ''; document.querySelector('#form-departement').value = e.suggestion.administrative || ''; document.querySelector('#country').value = e.suggestion.country || ''; }); })(); </script>

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

22 août 2017, 18:08

As-tu regardé dans la console de ton navigateur (Ctrl+Maj+i sous Firefox ou Chrome) ?
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 115 Messages

23 août 2017, 10:17

Merci de ton aide,
J'ai avancé sur mon problème cela fonctionne bien.
Mais il me reste un dernier point comment avoir plusieur pays comme la France, Belgique ... dans la recherche.

Code : Tout sélectionner

<form action="/billing" class="form"> <div class="form-group"> <input type="text" class="form-control" id="form-city" placeholder="ville"> <input type="text" class="form-control" id="form-zip" placeholder="Code postal"> <input type="text" class="form-control" id="form-region" placeholder="Région" /> <input type="text" class="form-control" id="form-departement" placeholder="Région" /> <input type="text" class="form-control" id="country" placeholder="Pays" /> </div> </form> <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> <?php $appId = 'xxxx'; $apiKey = 'xxxx'; //$places = \AlgoliaSearch\Client::initPlaces($appId, $apiKey); //$result = $places->search(''); //var_dump($result); ?> <script> (function() { var placesAutocomplete = places({ container: document.querySelector('#form-city'),
countries : 'fr',

Code : Tout sélectionner

type: 'city', templates: { value: function(suggestion) { return suggestion.name; } } }); placesAutocomplete.on('change', function resultSelected(e) { document.querySelector('#form-zip').value = e.suggestion.postcode || ''; document.querySelector('#form-region').value = e.suggestion.administrative || ''; document.querySelector('#form-departement').value = e.suggestion.administrative || ''; document.querySelector('#country').value = e.suggestion.country || ''; }); })(); </script>

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

23 août 2017, 10:44

Tu as indiqué countries:'fr'
Il te suffit de lire la doc pour essayer de voir si tu peux mettre plusieurs pays au paramètre countries : https://community.algolia.com/places/do ... -countries
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 115 Messages

24 août 2017, 09:09

Merci beaucoup @rthur,

J'avais parcouru la doc mais je n'avais pas vue ce point merci encore.
résolue,

Petit nouveau ! | 2 Messages

28 sept. 2019, 04:05

Bonjour,

Avez-vous pu créer un champ pour les départements genre: Rhône, Ain,... car sur la documentation de Algolia Place je ne trouve aucune indication pour afficher les départements mais uniquement les régions.

Merci pour votre aide.

Mammouth du PHP | 643 Messages

28 sept. 2019, 10:26

Perso je récupère le codepostal et avec j'ai le département et la région:
Je m'explique, dans ton formulaire tu récupères le codepostal comme ça par exemple:
'codepostal'=>$_POST['codepostal'],  // Ex: 38100
Donc si on utlise substr on peut récupère les 2 premiers chiffres:
$id_departements = substr($_POST['codepostal'], 0, -3); // Ex: 38


Du coup via un array tu peut avoir la région:

$aRegion = array(1 => 'Alsace', 2 => 'Aquitaine', 3 => 'Auvergne', 4 => 'Basse-Normandie', 5 => 'Bourgogne', 6 => 'Bretagne', 7 => 'Centre',  8=> 'Champagne-Ardenne', 9 => 'Corse', 10 => 'Franche-Comté', 11 => 'Haute-Normandie', 12 => 'Ile-de-France', 13 => 'Languedoc-Roussillon', 14 => 'Limousin', 15 => 'Lorraine', 16 => 'Midi-Pyrénées', 17 => 'Nord-Pas-de-Calais', 18 => 'Pays-de-la-Loire', 19 => 'Picardie', 20 => 'Poitou-Charentes', 21 => 'Provence Alpes Côte-d-Azur', 22 => 'rhone-alpes', 23 => 'Outre-Mer');
	

	
		
	$aDepartement = array(
							1 => array(67 => 'Bas-Rhin', 68 => 'Haut-Rhin'),
							2 => array(24 => 'Dordogne', 33 => 'Gironde', 40 => 'Landes', 47 => 'Lot-et-Garonne', 64 => 'Pyrénées-Atlantiques'),
							3 => array('03' => 'Allier', 15 => 'Cantal', 43 => 'Haute-Loire', 63 => 'Puy-de-Dôme'),
							4 => array(14 => 'Calvados', 50 => 'Manche', 61 => 'Orne'),
							5 => array(21 => 'Côte-d\'Or', 58 => 'Nièvre', 71 => 'Saône-et-Loire', 89 => 'Yonne'),
							6 => array(22 => 'Côtes d\'armor', 29 => 'Finistère', 35 => 'Ille-et-Vilaine', 56 => 'Morbihan'),
							7 => array(18 => 'Cher', 28 => 'Eure-et-Loir', 36 => 'Indre', 37 => 'Indre-et-Loire', 41 => 'Loir-et-Cher', 45 => 'Loiret'),
							8 => array('08' => 'Ardennes', 10 => 'Aube', 51 => 'Marne', 52 => 'Haute-Marne'),
							9 => array('20' => 'Corse-du-Sud', '20' => 'Haute-Corse'),
							10 => array(25 => 'Doubs', 39 => 'Jura', 70 => 'Haute-Saône', 90 => 'Territoire-de-Belfort'),
							11 => array(27 => 'Eure', 76 => 'Seine-Maritime'),
							12 => array(75 => 'Paris', 77 => 'Seine-et-Marne', 78 => 'Yvelines', 91 => 'Essonne', 92 => 'Hauts-de-Seine', 93 => 'Seine-Saint-Denis', 94 => 'Val-de-Marne'),
							13 => array(11 => 'Aude', 30 => 'Gard', 34 => 'Hérault', 48 => 'Lozère', 66 => 'Pyrénées-Orientales'),
							14 => array(19 => 'Corrèze', 23 => 'Creuse', 87 => 'Haute-Vienne'),
							15 => array(54 => 'Meurthe-et-Moselle', 55 => 'Meuse', 57 => 'Moselle', 88 => 'Vosges'),
							16 => array('09' => 'Ariège', 12 => 'Aveyron', 31 => 'Haute-Garonne', 32 => 'Gers', 46 => 'Lot', 65 => 'Hautes-Pyrénées', 81 => 'Tarn', 82 => 'Tarn-et-Garonne'),
							17 => array(59 => 'Nord', 62 => 'Pas-de-Calais'),
							18 => array(44 => 'Loire-Atlantique', 49 => 'Maine-et-Loire', 53 => 'Mayenne', 72 => 'Sarthe', 85 => 'Vendée'),
							19 => array('02' => 'Aisne', 60 => 'Oise', 80 => 'Somme'),
							20 => array(16 => 'Charente', 17 => 'Charente-Maritime', 79 => 'Deux-Sèvres', 86 => 'Vienne'),
							21 => array('04' => 'Alpes', '05' => 'Hautes-Alpes', '06' => 'Alpes-Maritimes', 13 => 'Bouches-du-Rhône', 83 => 'Var', 84 => 'Vaucluse'),
							22 => array('01' => 'Ain', '07' => 'Ardèche', 26 => 'Drôme', 38 => 'Isère', 42 => 'Loire', 69 => 'Rhône', 73 => 'Savoie', 74 => 'Haute-Savoie'),
							23 => array(971 => 'Guadeloupe', 972 => 'Martinique', 973 => 'Guyane', 974 => 'La Réunion')	
						);

	// On recupere l'iD de la region grace au departement
	function regionIdByDepartement($id) {
		
		global $aDepartement;
		
		$region = NULL;
		foreach($aDepartement as $k => $v) {
			if(array_key_exists($id, $v)) { $region = $k; break; }
		}
	return $region;
			
	}

Coté insert en bdd du coup pour tes 3 champs tu te retrouves comme ça:
Après je ne sais pas comment sont nommées tes tables en bdd mais bon je te laisse faire :)
'id_region'=>regionIdByDepartement($id_departements),
'id_departements'=>$id_departements,
'codepostal'=>$_POST['codepostal'],

Petit nouveau ! | 2 Messages

29 sept. 2019, 01:09

Merci yoann38, mais je veux utiliser l'API de Algolia Places.