Google Place Autocomplete sur Ruby on Rails

Le principe consiste à parser et injecter les champs de votre base de données (localité, région administrative, code postal, etc…) à partir de l’adresse. L’utilisateur choisit depuis la liste suggérée son adresse.

Voilà ce que nous allons obtenir !

autocomplete en action

Google Place Autocomplete : Création des clés API Google

Nous allons utiliser Geocoder qui utilise l’API de géolocalisation de Google. Vous aurez droit à un certain nombre de requêtes gratuitement.

Pour connaitre les tarifs, cliquez ICI

Il faudra activer les librairies Maps Javascript API et Places API.

Connectez vous à Google API Console et créez un nouveau projet.

Google place autocomplete : Créer un nouveau projet

Recherchez la librairie Maps Javascript API et activez la.

Google place autocomplete : Activer Maps Javascript API

Créez l’identifiant associé à cette API.

Google place autocomplete : Créer les identifiants

Cette clé serveur sera ajoutée plus tard dans notre projet Ruby on Rails

Google place autocomplete : Clé API créée

Une fois la clé ajoutée, vous pouvez la nommer, ici Geocoding Server key.

Google place autocomplete : Geocoding server key

Recherchez la librairie Places API et activez la.

Google place autocomplete : activer Google Place Web Service

Cliquez sur l’icône Identifiants, sélectionnez les paramètres de la clé API et sur RESTREINDRE LA CLÉ.

Google place autocomplete : clé restreinte

Cochez la restriction http, entrez une restriction en locale localhost:3000/* et pour votre dépôt heroku https://<VotreNomDeProjet>.herokuapp.com/*

Pour finir, cliquez sur Enregistrer.

Votre clé est opérationnelle

Google place autocomplete : clé opérationnelle

Google place Autocomplete : c’est parti !

Créez un nouveau projet avec le nom de votre choix, ici “Google_place_autocomplete” en précisant l’utilisation d’une base de données PostgreSQL. Le scaffold va nous générer les fonctions de base du CRUD (Create Read Update Delete) et nous servir pour la démo.

$ rails new google_place_autocomplete -d postgresql
$ cd google_place_autocomplete
$ rails generate scaffold Autocomplete address:string street_number:integer locality:string route:string administrative_area_level_1:string country:string postal_code:integer
$ git init
$ git add .
$ git commit -m "First commit"
$ hub create
$ git push origin master
$ rails db:create && rails db:migrate

Accédez au répertoire google_place_autocomplete depuis votre éditeur de codes. Dans mon cas, j’y accède depuis sublime text en entrant subl . depuis la console et ouvrez routes.rb avec CTRL+P.

# app/config/routes.rb 
Rails.application.routes.draw do
 resources :autocompletes
 root to: 'autocompletes#new'
end 

Ajoutez à votre Gemfile les gems ‘geocoder’, ‘figaro’et ‘jquery-rails’

# gemfile
# [...]
gem "geocoder"
gem "figaro"
gem 'jquery-rails' 
# [...]

Effectuez l’installation à l’aide de la commande bundle install depuis l’invite de commande.

$ bundle install
$ rails generate geocoder:config
$ bundle exec figaro install

Ajoutez jquery à votre application.js.

// app/assets/javascripts/application.js
//= require jquery
//= require rails-ujs
//= require turbolinks
//= require_tree .

Ouvrez le fichier geocoder.rb.

# config/initializers/geocoder.rb
Geocoder.configure(
   lookup:    :google,
   api_key:   ENV['GOOGLE_API_SERVER_KEY'],
   use_https: true,
   # [...]
) 

Mettez à jour le javascript_include_tag depuis le application.html.erb.

# app/views/layouts/application.html.erb
# [...]
<%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?libraries=places&key=#{ENV['GOOGLE_API_SERVER_KEY']}" %>
</head>
<body>
 <%= yield %>
 <%= javascript_include_tag 'application' %>
</body> 

Ajoutez vos clés API de Google à votre application.yml.

# config/application.yml
GOOGLE_API_SERVER_KEY: "AIzaSyBrbIg_6JdVD0tL6brWJ2qorlSXs8kwZps"

Pour finir, créez le fichier autocomplete.js et ajoutez le code javascript ci-dessous.

# app/assets/javascripts/autocomplete.js
$(document).on('turbolinks:load', function() {
function initializeAutocomplete(id) {     
     var element = document.getElementById(id);
     if (element) {
       var autocomplete = new google.maps.places.Autocomplete(element, { types: ['geocode'], componentRestrictions: {country: 'fr'} });
       google.maps.event.addListener(autocomplete, 'place_changed', onPlaceChanged);
       }
}

function onPlaceChanged() {
     var place = this.getPlace();     

     // console.log(place);  // Uncomment this line to view the full object returned by Google API.     

for (var i in place.address_components) {
 var component = place.address_components[i];
 for (var j in component.types) {  // Some types are ["country", "political"]
  var type_element = document.getElementById(component.types[j]);
  if (type_element) {
   type_element.value = component.long_name;
   }
  }
 }
}   
google.maps.event.addDomListener(window, 'load', function() {
 initializeAutocomplete('autocomplete_address');   
 }); 
}); 

En ajoutant componentRestrictions: {country: ‘fr’} nous limitons la recherche en France

Pour aller plus loin dans la limitation de la recherche cliquez ICI

Changez l’id des champs de votre formulaire comme ci-dessous pour permettre l’auto-complétion une fois l’adresse renseignée.

# app/views/_form.html.erb
# [...]
<div class="field">
 <%= form.label 'Adresse' %>
 <%= form.text_field :address, placeholder: "Entrez votre adresse", id: :autocomplete_address %>
</div>

<div class="field">
 <%= form.label 'N° de voie' %>
 <%= form.number_field :street_number, id: :street_number %>
</div>

<div class="field">
 <%= form.label 'Ville' %>
 <%= form.text_field :locality, id: :locality %>
</div>
 
<div class="field">
 <%= form.label 'Nom de la voie' %>
 <%= form.text_field :route, id: :route %>
</div>

<div class="field">
 <%= form.label 'Région' %>
 <%= form.text_field :administrative_area_level_1, id: :administrative_area_level_1 %>
</div>

<div class="field">
 <%= form.label 'Pays' %>
 <%= form.text_field :country, id: :country %>
</div>

<div class="field">
 <%= form.label 'Code postal' %>
 <%= form.number_field :postal_code, id: :postal_code %>
</div>
# [...] 

Google place Autocomplete : Avec du style !

Pour le matériel design, plutôt que d’utiliser Bootstrap, nous allons utiliser Materialize

Ajoutez à votre Gemfile la gem materialize-sass.

# gemfile
gem 'materialize-sass', '~> 1.0.0'

Installez la gem depuis votre invite de commande.

$ bundle install

Supprimez le fichier application.css depuis app/assets/stylesheets/application.css et créez le fichier application.scss pour importer les styles de materialize.

# app/assets/stylesheets/application.scss 
@import "materialize"; 
@import "materialize/components/color-variables";
$primary-color: color("blue", "lighten-2") !default;
$secondary-color: color("yellow", "base") !default;
@import 'materialize'; 

Nous allons centrer tous les éléments de notre page grâce au système Flexbox

A la suite de votre application.scss ajoutez le style scss ci-dessous pour centrer les éléments.

# app/assets/stylesheets/application.scss
# [...]
.flexbox {
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;   
   .actions {
      text-align: center;
      margin-top: 20px;
   }
} 

Ajoutez la balise .flexbox à la vue new.html.erb.

# app/views/autocompletes/new.html.erb 
<div class="flexbox">   
 <h1>New Autocomplete</h1>   
 <%= render 'form', autocomplete: @autocomplete %>
 <%= link_to 'Back', autocompletes_path %> 
</div> 

Modifiez le submit de votre form pour l’autocomplete.

# app/views/_form.html.erb
# [...]
<div class="actions">
 <div class="btn waves-effect waves-light">
  <%= form.submit "Rechercher" %>
 </div>
</div>
# [...] 

Pour voir le résultat, cliquez ICI

Pour voir les sources, cliquez ICI

signature Pierre-Christophe

2 Commentaires

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.