Voilà vu que l'on ne trouve rien pour cakephp 2.4.5 à ce sujet, pouvez vous m'aider pour finaliser un formulaire account?
L'idée est que lorsque l'utilisateur tape son code postal ou sa ville, dès les 3 premières frappes de caractères, cela liste toutes les villes ayant ce code postal et au clique sur la ville que l'on veut cela remplisse tous les champs: code postal, ville, département, région et pour finir soyons fou le pays.

Quand l'utilisateur clique sur le bouton envoyer cela doit enregistrer toutes les données dans users en base de données.

Mes tables:

users:
    - id int clé primaire,
    - name
    - adresse_1
    - adresse_2
    - zip_code
    - cities_id int indexé
    - departments_id int indéxé
    - regions_id int indéxé
    - country_id
cities:
    - id int clé primaire,
    - name
    - slug 
    - departments_id int indéxé
    - regions_id int indéxé

departments
    - id int clé primaire,
    - name
    - slug 
    - regions_id int indéxé
regions
    - id int clé primaire,
    - name
    - slug

Mes models

<?php
// User model named by User.php
App::uses('AppModel', 'Model');
class User extends AppModel{
    public $name = 'User';
}
// City model named by City.php
App::uses('AppModel', 'Model');
class City extends AppModel{
    public $name = 'City';
    public $belongsTo = array('Department', 'Region');
    public $hasMany = array('Announce');
    public $order = 'City.id ASC';
}
// Department model named by Department.php
App::uses('AppModel', 'Model');
class Department extends AppModel{
     public $name = 'Department';
     public $belongsTo = array('Region');
     public $hasMany = array('City');
     public $order = 'Department.id ASC';
}
// Region model named by Region.php
App::uses('AppModel', 'Model');
class Region extends AppModel{
    public $name = 'Region';
    public $hasMany = array('Announce', 'Department', 'City');
    public $order = 'Region.id ASC';
}

Ma vue account.ctp

<!-- app/View/Users/account.ctp --<
    <?= $this->Form->input('User.username', array(
    'label' => array('text' => "login")
    )); ?>
    <?= $this->Form->input('User.adresse_1', array(
    'label' => array('text' => "Adresse 1"),
    )); ?>
    <?= $this->Form->input('User.adresse_2', array(
    'label' => array('text' => "Adresse 1"),
    )); ?>
    <?= $this->Form->input('User.zip_code', array(
    'label' => array('text' => "Code postal", 'class' => 'col-lg-4 text-right p0r m10r'),
     'id' => 'cp'
     )); ?>
    <?= $this->Form->input('User.cities_id', array(
    'label' => array('text' => "Ville"),
    'id' => 'ville'
    )); ?>
    <?= $this -> Form -> input ('User.departments_id',array (
    'label' => array('text' => "Département"),
    'id' => 'departement',
    )); ?>
    <?= $this->Form->input('User.regions_id',array(
    'label' => array('text' => "Région"),
    'id'=>'region',
    )); ?>
    <?= $this->Form->input('User.country_id',array(
    'label' => array('text' => "Pays"),
    'id'=>'pays',
    )); ?>

Auparavant: suis-je obligé de répéter les departments_id, regions_id partout?
Maintenant tout est histoire de controller et d'action: Je ne sais plus comment faire. tout ce que j'ai essayé ne marche pas.

Merci d'avance de l'aide très très précieuse et du temps que vous m'accorderez!

21 réponses


Bonjour.
Tu pourrais tout simplement dans ton formulaire faire un select sur les villes et les départements via json par exemple, puis lors de la récupération des données, tu récupères la donnée de la ville sélectionnée.
Sur ce, tu fais un find avec le comportement Containable pour récupérer les données nécessaires, par exemple :

if($this->request->is('post') && !empty($this->request->data)){
        $complement = $this->User->City->find('first', array(
                                'conditions' => array('City.id' => $this->request->data'City']'id']),
                                'fields' => array('City.id', 'City.departments_id', 'City.regions_id')
                                )
        );
        $save = array(
                      'id' => $this->Auth->user('id'), 
                      'username' => $this->request->data'User']'username'], 
                      'adresse_1' => $this->request->data'User']'adresse_1'], 
                      'adresse_2' => $this->request->data'User']'adresse_2'], 
                      // 'zip_code' => $this->request->data'User']'zip_code'], pour ça il faudrait avoir le code postal dans la table cities 
                      'cities_id' => $complement'City']'id'], 
                      'departments_id' => $complement'City']'departments_id'], 
                      'regions_id' => $complement'City']'regions_id'] 
                      );
        if($this->User->save($save)){
            /* Code */
        } else {
            /* Code */
        }        
    }

que tu mets bien sûr dans la fonction qui permet d'éditer les informations.
Sinon il te faut une requête javascript pour chaque info.

  • Le code postal permet de sélectionner la ville (action de l'utilisateur)
  • La ville permet de récupérer le département correspondant (requête via javascript retourne celui-ci)
  • Le département permet de récupérer la région correspondante (requête via javascript retourne celle-ci)
    Par contre je ne comprends pas pourquoi tu veux faire ça, car l'utilisateur pourra modifier les infos liées et si tu utilises le disabled sur les input, je ne suis pas sur que le javascript puisse y modifier les infos.
    De plus, je trouve que vous êtes beaucoup à un peu trop compter sur le javascript, vous ne devriez pas trop.
mimosa21
Auteur

Bonjour Lartak11,
Merci encore de me venir en aide :)

Tu pourrais tout simplement dans ton formulaire faire un select sur les villes et les départements via json par exemple, puis lors de la récupération des données, tu récupères la donnée de la ville sélectionnée.

C'est bien là le problème! C'est loin d'être simple pour moi. Je construis ce formulaire depuis au moins 15 jours et je n'arrive à plus rien de constructif.

La seule chose qui marche pour l'instant c'est que lorsque je choisi ma région, je choisis dans la liste des départements de cette région uniquement. Sujet ici, je vais chercher la ville dans la liste en faisant rouler ma roue de souris et le tout s'enregistre dans ma table users.
Mais là j'avoue que pour ce que tu me demandes, je n'y arrive pas car tout ce que je trouve je n'arrive pas à le mettre en place.

Pour les villes, je dois faire le même système qu'entre mes villes et mes départements?
PS: Mes codes postaux sont bien en table cities aussi.

Bonjour et de rien :).
Dans le code d'exemple que je t'ai mis, c'était pour te proposer de seulement faire renseigner par l'utilisateur sa ville puis sans faire de requêtes javascript supplémentaire, lors de la soumission du formulaire, de récupérer les informations liées à la ville renseignée par l'utilisateur puis de sauvegarder les données, ensuite il te suffira de récupérer les données quand tu en as besoin dans les tables nécessaires via le comportement Containable en utilisant les *_id qui se trouvent dans ta table users pour les présenter à l'utilisateur.
Ce n'est pas nécessaire de montrer les informations adjacentes (départements, régions) à l'utilisateur dans le formulaire.
Du moment que dans le select pour la ville que le json renvoie des labels du type : Carcassonne (11000) , ça lui suffit pour voir qu'il sélectionne bien sa ville.
Il est inutile de faire trop de requêtes javascript pour faire du surplus dans un formulaire.
Pour le code postal j'avais mis ça, car dans le schéma SQL que tu as montré, il n'y a aucun champ concernant le code postal dans la structure de la table cities.

mimosa21
Auteur

ok, j'ai compris (enfin je crois):
Je ne mets pas les champs départements et région dans mon formulaire?

Tu n'en as pas besoin et l'input, zip_code non plus, tu mets juste pour la ville, vu que lors de la soumission du formulaire, dans la fonction de ton controller tu peux récupérer leurs ID dans la table cities juste avec l'ID de la ville, vu que dans celle-ci tu as les ID de la région et du département correspondant à la ville renseignée.
Après tu fais comme tu veux, mais ce n'est pas la peine d'afficher des inputs superflus à ce que tu veux faire.

mimosa21
Auteur

Merci Lartak de me donner un coup de main, parce que là je galère vraiment avec ce truc.
Je suis en train de modifier tout ça. j'essaye de faire une autocompletion sur ma ville avec mon code postal comme Carcassonne (11000), mais l'autocomplétion c'est une bête noire, pour l'instant je n'ai pas le résultat voulu.
Je fini ce que j'ai commencé et après j'étale ( :( ça va pô ête bô)

mimosa21
Auteur

Bon ben, je viens avec une ébauche qui bien évidemment ne marche pas!
ma vue account.ctp

<!-- app/View/Users/account.ctp --><!-- les scripts jquery et jquery-ui sont sur default.ctp -->
 <?php
    echo $this->Html->css(array('//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui'));
    echo $this->Html->css(array('bouton_radio'));
?>
<style>
    #project-label { display: block; font-weight: bold; margin-bottom: 1em; }
    #project-description { margin: 0; padding: 0; }
</style>
<script>
$(function() {
$( "#project" ).autocomplete({
minLength: 0,
source: '/cities/getByCity', // ça je pense que ce n'est pas bon
focus: function( event, ui ) {
$( "#project" ).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$( "#project" ).val( ui.item.label );
$( "#project-id" ).val( ui.item.value );
$( "#project-description" ).html( ui.item.desc );
return false;
}
})
.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
});
</script>
    <?= $this->Form->input('User.username', array(
    'label' => array('text' => "login")
    )); ?>
    <?= $this->Form->input('User.adresse_1', array(
    'label' => array('text' => "Adresse 1"),
    )); ?>
    <?= $this->Form->input('User.adresse_2', array(
    'label' => array('text' => "Adresse 1"),
    )); ?>
    <?= $this->Form->input('User.zip_code', array(
    'label' => array('text' => "Code postal", 'class' => 'col-lg-4 text-right p0r m10r'),
     'id' => 'cp'
     )); ?>
// Champs pris sur la doc de jquey.ui qui me servent pour l'autocomplétion de ma ville
    <?= $this->Form->input('User.cities_id', array(
    'label' => array('text' => "Ville"),
    'id' => 'project'
    )); ?>
<input type="hidden" id="project-id">
<p id="project-description"></p>

Ce que j'ai mis dans CitiesController:

public function getByCity() {
        $cities_id = $this->request->data'User']'cities_id'];
        if ($this->request->is('ajax')) {
            $this->autoRender = false;
            $this->layout = 'ajax';
            $results = $this->City->find('first', array('fields' => array('City.name'),
                'conditions' => array('City.name LIKE ' => $this->request->query'term'] . '%'),
                'group' => array('City.name'),
                'recursive' => -1
            ));
        $cities = '';
        $this->set('cities', $cities);          
        echo json_encode($cities);
        }
    }

Là du coup je ne sais plus dans quel sens je dois continuer.

Perso moi j'arrête de galérer avec les villes, j'utilise adresspicker

:o
Mais c'est génial ce truc !

mimosa21
Auteur

Bonjour à vous deux,
Tu l'utilises comment adresspicker amethyste?

Alors je fais ça de manière un peu trash : dans ma table users, j'ai un champ pour chaque valeur retournée par le plugin (address, locality, district, postal_code,lat, lng,...), et en plus j'ai un champ complément pour les cedex, bis, appartement, ...
Alors Ok ca fait du doublon dans la base, mais j'en avais marre de gérer les bases de ville, regions, etc..

Attention, si tu l'utilises, il faut garder la possibilité de remplir manuellement le formulaire entier car des fois notre ami Gmap ne trouve pas l'adresse. en revanche, finit les erreurs dans l'orthographe et bonjour la geoloc de tes membres :)

mimosa21
Auteur

Bon ça devient un vrai casse tête ce truc.j'ai téléchargé addresspicker sur ce github ici. J'ai pris le dossier "addresspicker" pas le master car rien qu'en l’essayant comme ça toujours dans mes téléchargements il ne marchait pas.
Je mets le css dans mon webroot/css comme ceci:
dossier addresspicker/demos: demo.css
dossier addresspicker/demos/themes/base/:

  • jquery.ui.accordion.css
  • jquery.ui.all.css
  • jquery.ui.autocomplete.css
  • jquery.ui.base.css
  • jquery.ui.button.css
  • jquery.ui.core.css
  • jquery.ui.datepicker.css
  • jquery.ui.dialog.css
  • jquery.ui.progressbar.css
  • jquery.ui.resizable.css
  • jquery.ui.selectable.css
  • jquery.ui.slider.css
  • jquery.ui.tabs.css
  • jquery.ui.theme.css

Dans mon dossier webroot/js:
dossier addresspicker/src:

  • jquery.ui.addresspicker.js

Je crée dans mon UsersController une action
public function account_essai(){
}
qui ne fait rien.
Je crée ma vue account_essai.ctp comme ceci: (copier collé de index.html du github en modifiant juste les appels au js et css pour que ça corresponde à cakephp:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>jquery-addresspicker demo (a jQuery UI widget)</title>
    <?php echo $this->Html->css(array('addresspicker/demos/themes/base/jquery.ui.all')); ?>
    <?php echo $this->Html->css(array('addresspicker/demos/demo')); ?>
    <?php echo $this->Html->script('http://maps.google.com/maps/api/js?sensor=false'); ?>
    <?php echo $this->Html->script('http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'); ?>
    <?php echo $this->Html->script('http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js'); ?>
    <?php echo $this->Html->script('addresspicker/src/jquery.ui.addresspicker.js'); ?>
  <script>
  $(function() {
    var addresspicker = $( "#addresspicker" ).addresspicker({
      componentsFilter: 'country:FR'
    });
    var addresspickerMap = $( "#addresspicker_map" ).addresspicker({
      regionBias: "fr",
      updateCallback: showCallback,
      mapOptions: {
        zoom: 4,
        center: new google.maps.LatLng(46, 2),
        scrollwheel: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      },
      elements: {
        map: "#map",
        lat: "#lat",
        lng: "#lng",
        street_number: '#street_number',
        route: '#route',
        locality: '#locality',
        administrative_area_level_2: '#administrative_area_level_2',
        administrative_area_level_1: '#administrative_area_level_1',
        country: '#country',
        postal_code: '#postal_code',
        type: '#type'
      }
    });
    var gmarker = addresspickerMap.addresspicker( "marker");
    gmarker.setVisible(true);
    addresspickerMap.addresspicker( "updatePosition");
    $('#reverseGeocode').change(function(){
      $("#addresspicker_map").addresspicker("option", "reverseGeocode", ($(this).val() === 'true'));
    });
    function showCallback(geocodeResult, parsedGeocodeResult){
      $('#callback_result').text(JSON.stringify(parsedGeocodeResult, null, 4));
    }
    // Update zoom field
    var map = $("#addresspicker_map").addresspicker("map");
    google.maps.event.addListener(map, 'idle', function(){
      $('#zoom').val(map.getZoom());
    });
  });
  </script>
</head>
<body>
  <a href="http://github.com/sgruhier/jquery-addresspicker"><img style="position: absolute; top: 0; left: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_left_green_007200.png" alt="Fork me on GitHub" /></a>
<div class="demo">
  <h1>jquery-addresspicker demo (a jQuery UI widget)</h1>
  <h2>Default address picker, only autocomplete.</h2>
  <p>
    Default address picker. It's just a jQuery autocomplete filled by google map geocoder suggestions.<br/>
    Try to enter an address like <em>Saint</em> and you'll see suggests
  </p>
  <div class='input'>
    <label>Address : </label><input id="addresspicker" />
  </div>
  <h2>Address picker, with instant display selection on map.</h2>
  <p>
    Same but the map on the left displays selected address, even while you navigate in autocomplete suggestions.<br/>
    Lat and Lng fields are just for information, they should be hidden inputs.<br/><br/>
    You can even adjust marker position on the map.<br/>
  </p>
  <div class='clearfix'>
    <div class='input input-positioned'>
      <label>Address : </label> <input id="addresspicker_map" /> <br/>
      <label>Locality: </label> <input id="locality" disabled=disabled> <br/>
      <label>District: </label> <input id="administrative_area_level_2" disabled=disabled> <br/>
      <label>State/Province: </label> <input id="administrative_area_level_1" disabled=disabled> <br/>
      <label>Country: </label> <input id="country" disabled=disabled> <br/>
      <label>Postal Code: </label> <input id="postal_code" disabled=disabled> <br/>
      <label>Lat: </label> <input id="lat" disabled=disabled> <br/>
      <label>Lng: </label> <input id="lng" disabled=disabled> <br/>
      <label>Zoom: </label> <input id="zoom" disabled=disabled> <br/>
      <label>Type: </label> <input id="type" disabled=disabled /> <br/>
    </div>
    <div class='map-wrapper'>
      <label id="geo_label" for="reverseGeocode">Reverse Geocode after Marker Drag?</label>
      <select id="reverseGeocode">
        <option value="false" selected>No</option>
        <option value="true">Yes</option>
      </select><br/>
      <div id="map"></div>
      <div id="legend">You can drag and drop the marker to the correct location</div>
    </div>
  </div>
  <div class='input-positioned'>
    <label>Callback: </label>
    <textarea id='callback_result' rows="15"></textarea>
  </div>
</div><!-- End demo -->
</body>
</html>

Qu'est ce qui peut clocher, ça ne marche pas!!!
j'ai même rajouté le

<?php echo $this->Html->script('bootstrap-typeahead.js'); ?>

de la version master.
Tout s'affiche bien sauf l'image et rien ne s'autocomplète. Une idée qui pourrait me faire avancer?
Est ce que ça interagit avec

<?php echo $this->Html->script('//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js'); ?>

de mon default.ctp qui est plus récent?

Cela fait deux semaines que je planche sur de l'autocomplète, qui pourtant est réputé facile à faire et moi je n'ai plus de cheveux à cause de ce truc qui me s'agace vraiment les nerfs.
HELP !!!

Bonjour.
Déjà, si tu mets une structure avec des head, meta et autres dans ta vue, penses à mettre

$this->layout = false; /* ou null, à vérifier */

dans ta fonction account_essai.
Sinon tu peux avoir des conflits entre les différents fichier javascript s'ils sont "dupliqués".

Cela fait deux semaines que je planche sur de l'autocomplète, qui pourtant est réputé facile à faire et moi je n'ai plus de cheveux à cause de ce truc qui me s'agace vraiment les nerfs.
Lorsque je suis dans ce cas là, je reprends tout à zéro et j'essaye de décomposer en petits éléments que j'arrive à intégrer et une fois ceci fait, je combine le tout.

Reprends les bases :

  • Quels sont mes besoins ? quel est le résultat attendu ?
  • Quelles sont les technologies que je souhaite utiliser ? (framework, plugin, ...).
  • Comment récupérer mes données (ici ville, CP, ...) ? via un webservice ? depuis un fichier ou une base de données que j'aurais rempli ?

Une fois que tu as répondu à ces questions, essaye de les réaliser une par une. Tu as un soucis avec l'autocomplete ? Créé toi un "toy project" dans lequel tu ne vas te concentrer que sur le fonctionnement du plugin. Peu importe les données de tests. Dans un premier de temps, fais le sur une page HTML et ensuite intègre le à ton application CakePHP.

Ici je ne vois pas bien la nécessité d'utiliser tes tables (cities, departments, regions), il y a plusieurs webservices qui se chargent de proposer tout ça déjà. Sachant que certains plugins d'autocomplétion proposent en plus un système de remote fetching via une url, ça permet de gagner un temps précieux. A moins que tu aies vraiment besoin que ces données soient en base.

Si tu n'as pas besoin de ces données en base, tu peux opter pour deux solutions :

  1. Tu fais appel au webservice (ex : http://www.geonames.org/) à chaque fois que la personne va sur la page.
  2. Tu récupères ces données dans un fichier que tu parseras (au format txt ou csv par exemple). C'est moins lourd que la base de données.

De plus, je trouve que vous êtes beaucoup à un peu trop compter sur le javascript, vous ne devriez pas trop.
Pourquoi ne devrait on pas ? JavaScript est un bon langage en soi. Est ce parce qu'il est désactivable ?

prbaron

Pourquoi ne devrait on pas ? JavaScript est un bon langage en soi. Est ce parce qu'il est désactivable ?

D'une certaine manière oui, car pour donner un exemple, il suffit de désactiver le javascript sur Facebook et vous remarquerez que l'on ne peut quasiment rien faire sur le site, ça montre à quel point les ressources doivent être extrêmement haute sur les appels javascript sur Facebook.
Et j'ai dit ça, car certaines personnes, dès que quelqu'un demande de l'aide sur quelque chose, quoi que ce soit, réponds direct avec une "solution" en utilisant javascript, alors que ça peut facilement être fait tout simplement avec du PHP, du HTML ou du CSS.
Je ne veux pas dire que je suis contre le javascript, bien au contraire, mais de là à l'utiliser pour tout et n'importe quoi, il ne faut pas abuser non plus.

A partir du moment ou tu connais les limites du JS (FE) et que tu sais ce que tu fais avec (donc pas de trucs qui mette la sécurité de ton site en péril) je ne vois absolument pas pourquoi soudainement il ne faudrait pas l'utiliser si tu peux faire ton truc en PHP.
Quand tu développes ton site dans ton coin et que ton cahier des charge ne spécifie pas que tu dois prendre en compte les 0.001% de paranos qui désactivent leur JS, tu peux bien faire ce que tu veux.

Le JS n'est pas la uniquement pour palier aux défauts du php, c'est aussi un langage en soit avec beaucoup de potentiel, et ce n'est définitivement pas la solution du pauvre quand il s'agit d'implémenter une fonctionnalité. La fluidité, la dynamique etc... est incomparable avec quoi que ce soit fait en PHP.

dès que quelqu'un demande de l'aide sur quelque chose, quoi que ce soit, réponds direct avec une "solution" en utilisant javascript, alors que ça peut facilement être fait tout simplement avec du PHP, du HTML ou du CSS Et alors ???? le PHP, l'HTML ou le CSS sont-ils plus noble que le JS, qu'il faille les choisir de préférence ? Meme si tu as las choix des armes, quelle raison ferait que tu devrait laisser le JS de coté ? même niveau performances, la gain est minime et absolument négligeable dans 99.99% des cas.

Ce débat "PHP vs. JS" est aussi stérile que le débat "PHP vs. python" ou "PHP vs. ruby". C'est une question de préférences perso et les avis extrémistes "on ne devrait utiliser le JS que si on n'a pas le choix" sont parfaitement infondés.

mimosa21
Auteur

En fait pour ce qui est de mon formulaire, j'avais pris pour compléter le département en fonction de la région Résumé ici un exemple qui s'appuie sur la librairie JSHelper de cakephp 2.x.
L'idée première de Lartak11 de ne faire qu'une recherche sur la ville en tapant les lettres une par une et que cela me ressorte une liste stylisée (Carcassonne(11000)) est très bien, je veux simplement avoir une recherche sur le code postal plutôt que sur la ville car un exemple si vous tapez saint dans la ville, avant de tomber sur la bonne ville, on risque d'avoir une sacrée pile de saint. Alors qu'avec le code postal on limite d'avantage. C'est une question d'opinion.
Maintenant, le but final est que lorsqu'un utilisateur s’enregistrera, il faudra les coordonnées gps de son lieu d'habitation, pour du covoiturage en autre. Dans ma table cities, j'ai les coordonnées gps des villes. C'est suffisant à mon avis pour dire ville à 5 - 10 -20 - 30 kms.

Voilà pour résumer, j'aimerais faire la même chose que le système de mes départements mais appliqué au code postal:
Je tape 89400 dans code postal et j'obtiens dans mon champs ville la liste déroulante:

  • Chichery 89400
  • Bassou 89400
  • Cheny 89400
    • les 8 autres villes.
      Je clique sur la ville qui me convient (je la sélectionne), et quand je valide mon formulaire mon cities_id s’enregistre dans ma table users.

Je vais donc reprendre l'idée de mon département et l'adapter suivant la librairie JSHelper de cakephp 2.x.

Si vous arrivez avant moi, chose très probable, merci de m'aider.

mimosa21
Auteur

Voilà où j'en suis
Mes tables:

users:
    - id int clé primaire,
    - name
    - adresse_1
    - adresse_2
    - zip_code
    - cities_id int indexé
    - departments_id int indéxé
    - regions_id int indéxé
    - country_id
cities:
    - id int clé primaire,
    - name
    - slug 
    - departments_id int indéxé
    - regions_id int indéxé

Mes models

<?php
// User model named by User.php
App::uses('AppModel', 'Model');
class User extends AppModel{
    public $name = 'User';
}
// City model named by City.php
App::uses('AppModel', 'Model');
class City extends AppModel{
    public $name = 'City';
    public $belongsTo = array('Department', 'Region');
    public $hasMany = array('Announce');
    public $order = 'City.id ASC';
}

Mes controllers:

<!--app/Controller/UsersController.php-->
<?php
App::uses('AppController','Controller');
class UsersController extends AppController{
    public $name = 'Users';
    public $uses = array('User','Region','Department', 'City');
    public $helpers = array('Js');

 public function account_essai() {
    if($this->request->is('post') && !empty($this->request->data)){
        $complement = $this->User->City->find('first', array(
                            'conditions' => array('City.zip_code' => $this->request->data'City']'zip_code']),
                            'fields' => array('City.id', 'City.departments_id', 'City.regions_id')
                            )
       );
        $save = array(
                  'id' => $this->Auth->user('id'),
                  'username' => $this->request->data'User']'username'],
                  'adresse_1' => $this->request->data'User']'adresse_1'],
                  'adresse_2' => $this->request->data'User']'adresse_2'],
                  'zip_code' => $this->request->data'User']'zip_code'],
                  'cities_id' => $complement'City']'id']
                  );
        if($this->User->save($save)){
            /* Code */
        } else {
            /* Code */
        }    
    }
  } 
}  
<!--app/Controller/CitiesController.php-->
<?php
App::uses('AppController','Controller');
class CitiesController extends AppController{
    public function getByZipCode() {
        $cities_id = $this->request->data'User']'cities_id'];
        $zip_code = $this->request->data'User']'zip_code'];
        $cities = $this->City->find('list', array(
            'conditions' => array('City.zip_code' => $zip_code),
            'recursive' => -1
            ));
        $this->set('cities',$cities);
        $this->layout = 'ajax';
    }
}

Ma vue account_essai.ctp

<!-- app/View/Users/account_essai.ctp -->
    <?= $this->Form->input('User.username', array(
    'label' => array('text' => "login")
    )); ?>
    <?= $this->Form->input('User.adresse_1', array(
    'label' => array('text' => "Adresse 1"),
    )); ?>
    <?= $this->Form->input('User.adresse_2', array(
    'label' => array('text' => "Adresse 2"),
    )); ?>
    <?= $this->Form->input('User.zip_code', array(
    'label' => array('text' => "Code postal"),
     'id' => 'PostZipCodeId'
     )); ?>
    <?= $this->Form->input('User.cities_id', array(
    'label' => array('text' => "Ville"),
    'id' => 'PostCityId'
    )); ?>
<?php // Je ne sais pas comment m'y prendre avec les options et event options de la <a href="http://book.cakephp.org/2.0/fr/core-libraries/helpers/js.html">librairie</a>  
    $this->Js->get('#PostZipCodeId')->event('keyup',
    $this->Js->request(array(
        'controller'=>'cities',
        'action'=>'getByZipCode'
        ), array(
        'update'=>'#PostCityId',
        'async' => true,
        'method' => 'post',
        'dataExpression'=>true,
        'data'=> $this->Js->serializeForm(array(
            'isForm' => true,
            'inline' => true
            ))
        ))
    );

Ma vue get_by_zip_code.ctp

<!-- file path app/View/Cities/get_by_zip_code.ctp -->
<?php
    if(!empty($cities)){
        foreach ($cities as $key => $value):
?>
        <option value="<?php echo $key; ?>"><?= $value'City']'id']; ?></option>
<?php
        endforeach;
    } else {
?>
    <option value="">No Data</option>
<?php
    }
?>

mon layout ajax.ctp

<!-- layout/ajax.ctp -->
<?php echo $this->fetch('content'); ?>

et en bas de mon layout default.ctp

<?php echo $this->Html->script('//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js'); ?>
<?php
  if (class_exists('JsHelper') && method_exists($this->Js, 'writeBuffer')) echo $this->Js->writeBuffer();
  //Writes cached scripts
?>

Voilà. J'obtiens un résultat en demi teinte.
mon champ cities_id' est vide. Lorsque je tape un début de code postal mon champ cities_id se remplit de "No data", ce qui signifie qu'il va bien prendre les info dans ma vue get_by_zip_code.ctp.
Sauf que la je pense qu'il y a erreur dans mon code. et comme noté dans ma vue account_essai.
Je pense qu'il y a aussi un soucis avec les options et event options de la librairie
Qu'en pensez-vous?

@Vallyan : J'arrêtes là car j'en ai marre, c'est impossible de discuter avec vous sans que vous en fassiez un débat, surtout que vous déformez les propos, relies bien ce que j'avais répondu et tu remarqueras qu'au moins la moitié de ce que tu me reproche est infondé par rapport à ce que j'avais dit, car il n'a jamais été question pour moi de dire que ce n'est pas bien d'utiliser javascript et je n'ai jamais fait allusion à d'autres langages comme python ou autre, alors en parler ici c'est plus qu'inutile.
Bref, quelqu'un donne son avis et vous vous lancez un débat dessus alors que s'en est pas le sujet.
Sur ce, je ne répondrais plus sur le forum pendant un certain temps car c'est saoulant d'avoir à faire avec des gens comme toi.

mimosa21
Auteur

:(

mimosa21
Auteur

Bon après plusieurs jours de recherche, je n'arrive pas à utiliser Adresspicker.
MAIS HéHé!!!
J'ai une solution qui le copie et qui est calquée dessus (enfin pas pour tout).
J'ai suivi ce tutoriel.
Je l'ai adapté comme suit:
Ma vue account_essai

<!-- main.css = .ui-autocomplete dans toutouille.css -->
<?php echo $this->Html->script('http://maps.google.com/maps/api/js?sensor=false', array('inline' => false)); ?>
<?php echo $this->Html->script('addresspicker/js/jquery-1.10.2.js', array('inline' => false)); ?>
<?php echo $this->Html->script('addresspicker/js/jquery-ui-1.10.4.custom.min.js', array('inline' => false)); ?>
<?php echo $this->Html->script('addresspicker/js/main.js', array('inline' => false)); ?>

    <label>Address: </label><input id="address" type="text"/>
    <div id="map_canvas" style="width:300px; height:300px"></div><br/>
    <label>latitude: </label><input id="latitude" type="text" disabled=disabled> <br/>
    <label>longitude: </label><input id="longitude" type="text" disabled=disabled> <br/>

Mon controller:

<!--app/Controller/UsersController.php-->
<?php
App::uses('AppController','Controller');
class UsersController extends AppController{
    public function account_essai(){// Qui pour l'instant ne fait rien
    }
}

Mon main.css

//Useful links:
// http://code.google.com/apis/maps/documentation/javascript/reference.html#Marker
// http://code.google.com/apis/maps/documentation/javascript/services.html#Geocoding
// http://jqueryui.com/demos/autocomplete/#remote-with-cache

var geocoder;
var map;
var marker;

function initialize(){
//MAP
  var latlng = new google.maps.LatLng(41.659,-4.714);
  var options = {
    zoom: 16,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };

  map = new google.maps.Map(document.getElementById("map_canvas"), options);

  //GEOCODER
  geocoder = new google.maps.Geocoder();

  marker = new google.maps.Marker({
    map: map,
    draggable: true
  });

}

$(document).ready(function() { 

  initialize();

  $(function() {
    $("#address").autocomplete({
      //This bit uses the geocoder to fetch address values
      source: function(request, response) {
        geocoder.geocode( {'address': request.term }, function(results, status) {
          response($.map(results, function(item) {
            return {
              label: item.formatted_address,
              value: item.formatted_address,
              latitude: item.geometry.location.lat(),
              longitude: item.geometry.location.lng()
            }
          }));
        })
      },
      //This bit is executed upon selection of an address
      select: function(event, ui) {
        $("#latitude").val(ui.item.latitude);
        $("#longitude").val(ui.item.longitude);
        var location = new google.maps.LatLng(ui.item.latitude, ui.item.longitude);
        marker.setPosition(location);
        map.setCenter(location);
      }
    });
  });

  //Add listener to marker for reverse geocoding
  google.maps.event.addListener(marker, 'drag', function() {
    geocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if (results[0]) {
          $('#address').val(results[0].formatted_address);
          $('#latitude').val(marker.getPosition().lat());
          $('#longitude').val(marker.getPosition().lng());
        }
      }
    });
  });

});

J'obtiens bien la l'adresse demandée du type 49 rue des pruneaux, 47000 Agens, France (dans mon input id="address) et la longitude et latitude dans:

<label>latitude: </label><input id="latitude" type="text" disabled=disabled> <br/>
    <label>longitude: </label><input id="longitude" type="text" disabled=disabled> <br/>

Tout ça marche. Maintenant je voudrais récupérer l'adresse, le code postal, le département et la région et du coup le pays dans des inputs différents (comme pour la longitude et la latitude)

Là je coince comment m'y prendre. Il va de soit que les champs input seront:

<label>Adresse 1: </label><input id="route_1" type="text" disabled=disabled> <br/>
<label>adresse 2: </label><input id="route_2" type="text" disabled=disabled> <br/>

Pour coller au mieux à adressepicker

<label>Code postal: </label><input id="postal_code" type="text" disabled=disabled> <br/>
<label>Ville: </label><input id="locality" type="text" disabled=disabled> <br/>
<label>Département: </label><input id="administrative_area_level_1" type="text" disabled=disabled> <br/>
<label>Région: </label><input id="administrative_area_level_2" type="text" disabled=disabled> <br/>
<label>Pays: </label><input id="country" type="text" disabled=disabled> <br/>

Si vous avez une idée elle sera très bien venue.

Améthyste, tu m'as bien aidé et je t'en remercie :)