I am using the JavaScript Google places autocomplete API v3. It works fine but I was wondering if there was a way to force the selection from the autocomplete, that is input that will not accept any free form text. I looked at the docs and didn't see such an option but figured I would ask just to be safe. I'm sure I could work out a way to do it with some JavaScript but would prefer to use an already built method if it is available. Thanks!
13 Answers
Actually, what we did was the following:
- Every time a location is picked from the Auto complete list, we populate some hidden fields with some fields coming from the JSON response (city name, country name, longitude and latitude)
- When the form is submitted, we check if these fields have values, if they don't, it means that the user instead of selecting a location from the list, he just entered a value himself.
It is not solving the problem in a JS way, but still, it does the trick just fine!

- 909
- 2
- 14
- 27
-
5It's worth noting that you should also remove the values from these hidden inputs if the user removes a selected location and then manually enters a location. – digout Jan 26 '16 at 10:34
-
13It will not work. Suppose first I select the proper location from autocomplete, so based on that your hidden field values would fill and then if I remove some text from autocomplete box and then submit, in that case the wrong address will insert in your DB as the hidden field values are already having some values. – Milan Jul 22 '16 at 08:44
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"
type="text/javascript"></script>
<script>
var IsplaceChange = false;
$(document).ready(function () {
var input = document.getElementById('txtlocation');
var autocomplete = new google.maps.places.Autocomplete(input, { types: ['(cities)'] });
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
IsplaceChange = true;
});
$("#txtlocation").keydown(function () {
IsplaceChange = false;
});
$("#btnsubmit").click(function () {
if (IsplaceChange == false) {
$("#txtlocation").val('');
alert("please Enter valid location");
}
else {
alert($("#txtlocation").val());
}
});
});
</script>

- 164
- 1
- 4
-
2Try to add a description or explanation to help people understand how this solves the problem – Illidanek Jul 08 '14 at 13:42
-
If you type something and press `Enter` the `place_changed` event will be thrown and the get place object will be returned with a single property name with the text that you entered. – lcguida May 11 '15 at 20:07
The Google Places API does not currently support this feature. If you believe this would be a useful feature please submit a Places API - Feature Request.

- 4,397
- 1
- 23
- 21
-
1I'm using a workaround ... instead, I use the Autocomplete Prediction API to select by default the first result. – nicolasbui Jun 04 '15 at 13:04
-
http://code.google.com/p/gmaps-api-issues/issues/detail?id=8456 Vote, if you also affected. – Anton Bessonov Mar 29 '16 at 18:45
-
1Don’t do this. It’s a terrible idea since Google is often wrong. For new roads you’ll have a year-long delay until correct addresses are recognized, for instance. See answer below. – eraoul Feb 26 '18 at 04:45
The following solution did the trick for me (with jQuery). The idea is to use the blur()
event to force the last selected address once the input loses focus.
We add a timeout to prevent a conflict between the blur
and the place_changed
events.
Consider the following html:
<input type="text" placeholder="Your address" id="autocomplete">
And the following javascript :
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{types: ['geocode']});
autocomplete.addListener('place_changed', fillInAddress);
var currentAddress = {
line_1: "",
line_2: "",
zipcode: "",
city: "",
country: "",
lat: "",
lng: "",
one_liner: ""
};
function fillInAddress() {
var place = this.autocomplete.getPlace();
// reset the address
currentAddress = {
line_1: "",
line_2: "",
zipcode: "",
city: "",
country: "",
lat: "",
lng: "",
one_liner: place.formatted_address
};
// store relevant info in currentAddress
var results = place.address_components.reduce(function(prev, current) {
prev[current.types[0]] = current['long_name'];
return prev;
}, {})
if (results.hasOwnProperty('route')) {
currentAddress.line_1 = results.route;
}
if (results.hasOwnProperty('street_number')) {
currentAddress.line_1 = results.street_number + " " + currentAddress.line_1;
}
if (results.hasOwnProperty('postal_code')) {
currentAddress.zipcode = results.postal_code;
}
if (results.hasOwnProperty('locality')) {
currentAddress.city = results.locality;
}
if (results.hasOwnProperty('country')) {
currentAddress.country = results.country;
}
currentAddress.lat = Number(place.geometry.location.lat()).toFixed(6);
currentAddress.lng = Number(place.geometry.location.lng()).toFixed(6);
}
$('#autocomplete').blur(function() {
var address = $('#autocomplete').val();
// we set a timeout to prevent conflicts between blur and place_changed events
var timeout = setTimeout(function() {
// release timeout
clearTimeout(timeout);
if (address !== currentAddress.one_liner) {
$('#autocomplete').val(currentAddress.one_liner);
}
}, 500);
});
I hope this helps.

- 9,394
- 5
- 43
- 45
-
This is a nice solution. I didn't have access to place.formatted_address, so I had to just set one_liner to the current value of the autocomplete input field at the end of the fillInAddress function or use a more complex way to get the formatted_address : autocompleteObj.gm_bindings_.bounds[7].re.formattedPrediction – sFishman Jul 20 '20 at 09:40
-
Although I wouldn't be inclined to use the second option I suggested as it may not work in all scenarios and is rather ugly – sFishman Jul 20 '20 at 10:06
var options = {
language: 'en',
types: ['(cities)'],
};
var input = document.getElementById('city');
var autocomplete = new google.maps.places.Autocomplete(input, options);
input.addEventListener("change", function(){
input.value = "";
});
Quiting the value when the input changes works for me. It forces to use Google Places.

- 21
- 3
-
1I tried bunch of other solutions before I tried this, and must say, it works perfectly. Nice one! – 今際のアリス Jun 09 '21 at 21:26
I was having the same problem, below is a function that I came up with as a work-around. This could be used in combination with an event such as onchange or onkeyup. Hope it helps!
//Arguments:
address - string containing the place that you want to validate
address_success_div - div object specifically used for displaying validation
function is_location_valid(address, address_success_div)
{
var geocoder = new google.maps.Geocoder();
geocoder.geocode( {"address": address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
address_success_div.innerHTML = "SUCCESS";
}
else
{
address_success_div.innerHTML = "FAILURE";
}
});
}

- 29
- 3
You can use the input pattern tag, forcing the user to choose a predeterminate based on Google Autocomplete API.
The input:
<form>
<input type="text" onkeyup="changePatterns()" onchange="changePatterns()" id="autocomplete" required pattern="">
<input type="submit">
</form>
The JS file:
function changePatterns() {
let input = document.getElementById('autocomplete').value;
let regExp = new RegExp(' ', 'g');
input = input.replace(regExp, '%20');
let mapsURL = 'https://maps.googleapis.com/maps/api/place/autocomplete/json'
mapsURL += '?types=geocode';
mapsURL += '&key=YOUR-KEY-HERE';
mapsURL += `&input=${input}`;
const endpoint = 'middle.php';
let formData = new FormData();
formData.append('url', mapsURL);
fetch(endpoint, {
method: 'post',
body: formData
})
.then(blob => blob.json())
.then(response => {
const predictions = response.predictions;
let {length} = predictions;
let pattern = '';
for(let i = 0; i < length; i++){
pattern += i == 0 ? '' : '|';
pattern += predictions[i].description
}
const input = document.getElementById('autocomplete');
input.setAttribute('pattern', pattern);
});
}
I had to use a php intermediate because of problems with CORS policy:
<?php
header('Content-Type: application/json');
$url = $_POST['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //remove on upload
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "https://www.notmydomain.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);
echo $result;

- 11
- 2
I solved my issue using this code found here
<asp:TextBox runat="server" ID="TextBox1" />
<input type="button" id="btnSubmit" name="name" value="Validate" />
<div id="dvMap">
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyBE1J5Pe_GZXBR_x9TXOv6TU5vtCSmEPW4"></script>
<script type="text/javascript">
var isPlaceChanged = false;
google.maps.event.addDomListener(window, 'load', function () {
var places = new google.maps.places.Autocomplete(document.getElementById('<%= TextBox1.ClientID %>'));
google.maps.event.addListener(places, 'place_changed', function () {
isPlaceChanged = true;
var geocoder = new google.maps.Geocoder();
var place = places.getPlace();
var address = place.formatted_address;
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var mapOptions = { center: new google.maps.LatLng(latitude, longitude), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var marker = new google.maps.Marker({ position: new google.maps.LatLng(latitude, longitude), map: map });
} else {
alert("Request failed.")
}
});
});
});
$(function () {
$("#TextBox1").keydown(function () {
isPlaceChanged = false;
});
$("#btnSubmit").click(function () {
if (!isPlaceChanged) {
$("#TextBox1").val('');
alert("Please Enter valid location");
}
else {
alert($("#TextBox1").val());
}
});
});
</script>

- 7,771
- 5
- 39
- 55
Like they mentioned it's not supported in the Google Autocomplete API. I found a way to make it work by creating a hidden element that stores the selected places than check if it's equal to the autocomplete input.
/*----------------------------------------------------*/
/* check if it's valid address
/*----------------------------------------------------*/
function checkAddress(location, validLocation) {
if (location.val() == validLocation.val()) {
return true;
}
return false;
}
/*----------------------------------------------------*/
/* initialize auto complete address
/*----------------------------------------------------*/
function initialize() {
let input = document.getElementById('autocomplete-input');
let inputHidden = document.getElementById('autocomplete-input-hidden');
let options = {
types: ['(regions)'],
componentRestrictions: {country: "tn"}
};
let autocomplete =new google.maps.places.Autocomplete(input, options);
autocomplete.setFields(['formatted_address']);
autocomplete.addListener('place_changed', function () {
inputHidden.value= autocomplete.getPlace().formatted_address;
});
}
call the function in your main.
let location = $('#autocomplete-input');
let validLocation = $('#autocomplete-input-hidden');
checkAddress(location,validLocation);
and in your html:
<input id="autocomplete-input" type="text">
<input id="autocomplete-input-hidden" type="hidden" >

- 1,374
- 3
- 19
- 43
I found a simpler solution that I implemented with jquery validation plugin, but that's not a must. I just used a class name as a flag to show whether the field was valid (i.e. the user made a selection from Google) or invalid (i.e. they typed their own stuff). I created two functions, one to add the class "err" and one to take it away.
function invalidate(element_id){
$('#' + element_id).addClass('err');
}
function makeValid(element_id){
if ($('#' + element_id).hasClass('err')){
$('#' + element_id).removeClass('err');
}
$('#' + element_id).valid(); //this is a method from jquery validation plugin to check validity of a field
}
Then, onkeydown I called the "invalidate" function to flag that the input element had been typed into.
document.getElementById("element_id").setAttribute('onkeydown', "invalidate('element_id')");
And at the end of the Google Autocomplete API (I did it at the end of the fillInAddress method), I called "makeValid" to remove the flag because the user has just chosen an option from the dropdown menu.
makeValid(userElementId);
Finally, I validated that the "err" class that I used as my flag for when the user typed instead of choosing an option is not present. Here I used jquery validation plugin, but you could use something else if desired.
jQuery.validator.addMethod("hasClassErr", function(value, element) {
return this.optional( element ) || !element.classList.contains("err");
}, jQuery.validator.format("Please choose an option from the dropdown menu."));
FORM_RULES = {
element_name: {required: true, 'hasClassErr': true}
};
$('#form_id').validate({
rules: FORM_RULES
});

- 137
- 9
see https://stackoverflow.com/a/52534805/4481226
Below doesn't work. just kept for history
An easier approach could be:
let placeInputEl = document.getElementById("placeInput");
let autcomplete = new google.maps.places.Autocomplete(placeInputEl);
placeInputEl.addEventListener("change", () => {
//this fires when the user changes to a non-selection / freeform text
doStuff(true);
});
autocomplete.addListener("place_changed", () => {
//this fires when the user selects a place from Google
doStuff(false);
});
function doStuff(isFreeText) {
//maybe clear the selection or do whatever you need to reset
if (isFreeText) {
placeInputEl.value = "";
return;
}
// handle a place selection
}
<input id="placeInput" />
this lets you clear the input, determine validation, reset the input, or whatever you want to do to make the selection mandatory.
the place_changed
event only fires when the user selects an input or hits enter.
the change
event fires before place_changed
so you may be able to apply your logic without interfering with google's api call

- 948
- 14
- 14
I solved the problem combining the suggestions on a couple of different answers from here. My Textfield where the user inputs the address is called txtPlaces. Here's my code:
var pac_input = document.getElementById('txtPlaces');
(function pacSelectFirst(input) {
// store the original event binding function
var _addEventListener = (input.addEventListener) ? input.addEventListener : input.attachEvent;
function addEventListenerWrapper(type, listener) {
// Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected,
// and then trigger the original listener.
if (type == "keydown") {
var orig_listener = listener;
listener = function(event) {
var suggestion_selected = $(".pac-item-selected").length > 0;
if ((event.which == 13 || event.which == 9) && !suggestion_selected) {
var simulated_downarrow = $.Event("keydown", {
keyCode: 40,
which: 40
});
orig_listener.apply(input, [simulated_downarrow]);
}
orig_listener.apply(input, [event]);
};
}
_addEventListener.apply(input, [type, listener]);
}
input.addEventListener = addEventListenerWrapper;
input.attachEvent = addEventListenerWrapper;
var autocomplete = new google.maps.places.Autocomplete(input);
})(pac_input);
$('#txtPlaces').blur(function(e){
selectFirstAddress(pac_input);
});
////Ensuring that only Google Maps adresses are inputted
function selectFirstAddress (input) {
google.maps.event.trigger(input, 'keydown', {keyCode:40});
google.maps.event.trigger(input, 'keydown', {keyCode:13});
}
This will properly react to Enter or Tab keys, as well as when the user selects another field. Hope this helps!

- 51
- 1
- 2
Hia I have managed to do that by creating the autocomplete object each time the user focuses the input field, and checking it's value each time it's blured:
var autocompleteField;
var input = document.getElementById('YOUR_INPUT');
$('#YOUR_INPUT').focus(function(e){
if(autocompleteField){
autocompleteField=null;
}
autocompleteField = new google.maps.places.Autocomplete(input);
});
$('#YOUR_INPUT').blur(function(e){
var results = autocompleteField.getPlace();
if(!results){
$(this).attr('value','');
}
});

- 532
- 4
- 4