9

I am using Google Maps API and the Autocomplete search feature. Currently, you must begin typing a location(city, state, zip, etc.) and then select a result from the dropdown for the map to center at that location. However, I would like to make this fool proof and set it up so that if someone types just a city or just a state and hits "enter" without selecting an Autocomplete result, it will still work. For instance, if someone types "New York" and hits "enter" without selecting a result in the dropdown, it will still center on New York.

I'm assuming this is accomplished by grabbing the first result from the Autocomplete dropdown if one is not selected manually.

I've added an event listener for the submission of the form, but not sure how to pass the first result into the "place" variable.

Here is my code:

function searchBar(map) {
    var input = document.getElementById('search-input');
    var searchform = document.getElementById('search-form');
    var place;
    var options = {componentRestrictions: {country: 'us'}};
    var autocomplete = new google.maps.places.Autocomplete(input, options);

    //Add listener to detect autocomplete selection
    google.maps.event.addListener(autocomplete, 'place_changed', function () {
        place = autocomplete.getPlace();
        center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
        map.setCenter(center);
        map.setZoom(5);
    });

    //Add listener to search
    searchform.addEventListener('submit', function() {
        center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
        map.setCenter(center);
        map.setZoom(5);
    });

    //Reset the inpout box on click
    input.addEventListener('click', function(){
        input.value = "";
    });
};

And here is a JSFiddle for experimentation.

user13286
  • 3,027
  • 9
  • 45
  • 100

3 Answers3

19

There is no implemented way to access the places in the dropdown. Basically what you see in the dropdown are not places, there are only predictions. The details for a prediction will be loaded when you select a prediction.

So you must select a prediction programmatically.

How to achieve it:

Another way than clicking on a prediction is to use the down-key, the keycode is 40. The API listens to keydown-events of the input.

So when you hit enter:

  1. trigger keydown with a keycode 40(down)
  2. trigger keydown with a keycode 13(enter)

    google.maps.event.addDomListener(input,'keydown',function(e){
             if(e.keyCode===13 && !e.triggered){ 
       google.maps.event.trigger(this,'keydown',{keyCode:40}) 
       google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}) 
     }
    });
    

Note: to avoid a infinite loop for the enter I've added a custom property triggered, so I'm able to bypass the triggered keydown inside the function.

Demo: http://jsfiddle.net/4nr4tdwz/1/

Dr.Molle
  • 116,463
  • 16
  • 195
  • 201
  • 1
    No doubt the best and smartest solution I could find in any thread. Well done discovering this hack! – Andreas Galster Dec 02 '15 at 18:42
  • How do I prevent the default form submission upon pressing enter? I have tried adding `return false` in the `if(e.keyCode===13 && !e.triggered){` bit, but it doesn't seem to do anything. – MAX POWER Aug 19 '18 at 17:39
  • In my example ( see the fiddle ) it will be achieved by setting the form-action ( to `javascript:void(0) ` ) – Dr.Molle Aug 20 '18 at 07:10
2

I added a filter to avoid keydown being triggered when user has already select any result from the autocomplete:

google.maps.event.addDomListener(input,'keydown',function(e){
    if(e.keyCode===13 && $('.pac-item-selected').length == 0 && !e.triggered){ 
    google.maps.event.trigger(this,'keydown',{keyCode:40}) 
    google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}) 
  }
});
Zirc75
  • 365
  • 3
  • 13
0

Helper function for setting initial/default location programmatically - e.g. from geolocation API.

    var triggerLocation = function(autocompleteInput, addressString) {
    var $locationInput = $(autocompleteInput).val(addressString).trigger('focus');
    var maxTries = 500;

    var autocompleteSelectionInterval = setInterval(function() {
        if (!--maxTries) {
            clearInterval(autocompleteSelectionInterval);
        }

        if ($('.pac-container .pac-item').length) {
            google.maps.event.trigger($locationInput[0], 'keydown', {
                keyCode : 40
            });

            google.maps.event.trigger($locationInput[0], 'keydown', {
                keyCode : 13
            });

            clearInterval(autocompleteSelectionInterval);
        }
    }, 10);
};

Example:

var autocomplete = new google.maps.places.Autocomplete($('#location')[0]);
triggerLocation('#location', 'New York');
kayz1
  • 7,260
  • 3
  • 53
  • 56