Reputation: 26281
How do I change the value of a Google Maps autocomplete field after the value has been changed?
My ultimate desire is to just show the address in this field, and the city, state, etc in separate fields.
As seen by http://jsbin.com/wiye/2/ (script duplicated below), I change the value, but it later changes back.
show just the street address in google.maps.event.addListener() asks the same question, but it no longer appears to work. Change the value in textbox of a google map autocomplete also asks the same question, but doesn't have an adequate answer.
Thank you
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Places search box</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js" type="text/javascript"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script>
$(function(){
var input_auto = document.getElementById('input_auto');
autocomplete = new google.maps.places.Autocomplete(input_auto,{types: ['geocode'],radius: 10});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
setTimeout(function(){$('#input_auto').val('yyy');},50);
alert('pause1');
console.log(autocomplete,input_auto);
input_auto.value='xxx';
//autocomplete.set('xxx');
//autocomplete.setValues('xxx');
alert('pause2');
});
});
</script>
</head>
<body>
<input id="input_auto" type="text">
</body>
</html>
Upvotes: 9
Views: 22670
Reputation: 417
The simplest way I've found to programmatically change the value of an Autocomplete input is to reinitialize the input field.
var input = document.getElementById(input_auto);
autocomplete = new google.maps.places.Autocomplete(input, option);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
// perform any functions based on place input
...
// change the value of your autocomplete to whatever you want
input.value = 'yyy';
// reinitialize with new input value
autocomplete = new google.maps.places.Autocomplete(input, option);
}
Upvotes: 4
Reputation: 68
You can fix this by adding event listeners to blur
and keydown
events to override the automatic value. Check out what I did below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Places search box</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js" type="text/javascript"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script>
$(function(){
var input_auto = document.getElementById('input_auto');
autocomplete = new google.maps.places.Autocomplete(input_auto,{types: ['geocode'],radius: 10});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
input_auto.addEventListener('blur', function() {
input_auto.value = 'yyy';
});
input_auto.addEventListener('keydown', function() {
input_auto.value = 'yyy';
});
setTimeout(function(){$('#input_auto').val('yyy');},1);
});
});
</script>
</head>
<body>
<input id="input_auto" type="text">
</body>
</html>
You can optionally add setTimeouts if you run into any problems.
Upvotes: -2
Reputation: 473
You're using a number of events that you don't need. When a user selects an address from the autocomplete options, autocomplete fires the place_changed
event. When that event fires, autocomplete populates the field that it's attached to.
Here's a more appropriately-structured answer to your problem that will enable you to "show the address in this field, and the city, state, etc in separate fields":
(function() {
var $inputAuto = $('#input_auto');
var addrComponents = {
streetNumber: {
display: 'short_name',
type: 'street_number'
},
streetName: {
display: 'long_name',
type: 'route'
},
cityName: {
display: 'long_name',
type: 'locality'
},
stateName: {
display: 'short_name',
type: 'administrative_area_level_1'
},
zipCode: {
display: 'short_name',
type: 'postal_code'
}
};
var autocomplete;
var autocompleteOptions = {
radius: 10,
types: ['geocode']
};
function initAutocomplete() {
autocomplete = new google.maps.places.Autocomplete($inputAuto[0], autocompleteOptions);
autocomplete.addListener('place_changed', setAddress);
};
function setAddress() {
var place = autocomplete.getPlace().address_components;
var streetAddr = [addrComponents.streetNumber, addrComponents.streetName];
var streetAddrDisplay = [];
// Add additional field values
place.forEach(function(placeComponent) {
streetAddr.forEach(function(streetAddrComponent) {
if (placeComponent.types[0] === streetAddrComponent.type) {
streetAddrDisplay.push(placeComponent[streetAddrComponent.display]);
}
// else if <additional field values>
});
});
var addrString = streetAddrDisplay.join(' ');
$inputAuto.val(addrString);
};
initAutocomplete();
}());
autocomplete.getPlace()
returns an object with a bunch of stuff that you can use for other Maps API calls. However, you just want the first object within that, address_components
. This is an array of matched address component objects. Each of these objects has a long_name
and short_name
that you'll use to populate your inputs. Each object also includes an array of types
that indicates what the strings represent (the 0 index is the unique identity of the object). In your case: street number (street_number
), street name (route
), city (locality
), county (administrative_area_level_2
), state (administrative_area_level_1
), country (country
), and zip (postal_code
).
In this example, the addrComponents
object contains easily-readable options for matching items in the place
array. In order to achieve your desired result of populating multiple fields, you just need to select the fields and set their contents with $inputName.val(desiredString)
.
As an additional reference, the Google Maps JavaScript API docs contain an example of exactly what you want to do.
Hope that helps. Good luck!
Upvotes: 1