Googlemaps places Autocomplete by className – JS loop Problem
I need to add Autocomplete to input fields by ClassName. I got it to work but Google does not sent the Address with Postalcode back.
So I am trying to use addListener to insert the formatted_address on the input field.
In this example the input[i] on the autocomplete.addListener is not working:
function initMap() { var input = $('.my_adresse'); for (i = 0; i < input.length; i++) { var autocomplete = new google.maps.places.Autocomplete(input[i], { types: ['address'], componentRestrictions: { 'country': ["de", "ch", "aut"] } }); autocomplete.addListener('place_changed', function() { var place = autocomplete.getPlace(); $(input[i]).val(place.formatted_address); }); } }
On this example only the last Element of the loop is working:
var input = $('.my_adresse'); for (i = 0; i < input.length; i++) { var autocomplete = new google.maps.places.Autocomplete(input[i], { types: ['address'], componentRestrictions: { 'country': ["de", "ch", "aut"] } }); var input_to_change= input[i]; autocomplete.addListener('place_changed', function() { var place = autocomplete.getPlace(); $(input_to_change).val(place.formatted_address); }); } }
Why am I getting just the last element of the loop? What is the best solution to get the Complete Address with postal code using Google Maps places Autocomplete?
One way to address the issue is with function closure, create a createAutocomplete
function to hold closure on the input and the autocomplete object:
function createAutocomplete(input, index) { var autocomplete = new google.maps.places.Autocomplete(input, { types: ['address'], componentRestrictions: { 'country': ["de", "ch", "aut"] } }); var input_to_change = input; autocomplete.addListener('place_changed', function() { var place = autocomplete.getPlace(); console.log(place); $(input).val(place.formatted_address); }); }
and call that in your loop:
for (i = 0; i < input.length; i++) { createAutocomplete(input[i], i); }
code snippet:
// This example requires the Places library. Include the libraries=places // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"> function initMap() { var map = new google.maps.Map(document.getElementById('map'), { center: { lat: -33.8688, lng: 151.2195 }, zoom: 13 }); var bounds = new google.maps.LatLngBounds(); var input = $('.my_adresse'); for (i = 0; i < input.length; i++) { createAutocomplete(input[i], i); } function createAutocomplete(input, index) { var autocomplete = new google.maps.places.Autocomplete(input, { types: ['address'], componentRestrictions: { 'country': ["de", "ch", "aut"] } }); var input_to_change = input; autocomplete.addListener('place_changed', function() { var place = autocomplete.getPlace(); console.log(place); if (place != null) { $(input).val(place.formatted_address); if (place.geometry.location) { var marker = new google.maps.Marker({ position: place.geometry.location, map: map, title: "" + index }); bounds.extend(marker.getPosition()); map.fitBounds(bounds); } } }); } }
/* Always set the map height explicitly to define the size of the div * element that contains the map. */ #map { height: 70%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="pac-card" id="pac-card"> <div> <div id="title"> Autocomplete search </div> </div> <div id="pac-container"> <input id="pac-input" class="my_adresse" type="text" placeholder="Enter a location"> </div> <div> <input class="my_adresse" type="text" placeholder="Enter a location"> </div> <div> <input class="my_adresse" type="text" placeholder="Enter a location"> </div> <div> <input class="my_adresse" type="text" placeholder="Enter a location"> </div> </div> <div id="map"></div> <!-- Replace the value of the key parameter with your own API key. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>