Google maps Places API V3 autocomplete - select first option on enter

A working answer for 2020.

I've combined the best answers on this page and written it in straightforward ES6. No jQuery, 2nd API request, or IIFE needed.

Basically, we simulate a ↓ (down-arrow) keypress whenever the user hits return inside the autocomplete field.

First, assuming in your HTML you have something like <input id="address-field">, set up the identification of your address field like this:

const field = document.getElementById('address-field') 

const autoComplete = new google.maps.places.Autocomplete(field)

autoComplete.setTypes(['address'])

Then add this on the next line:

enableEnterKey(field)

And then elsewhere in your script, to keep this functionality separate in your code if you'd like to, add the function:

  function enableEnterKey(input) {

    /* Store original event listener */
    const _addEventListener = input.addEventListener

    const addEventListenerWrapper = (type, listener) => {
      if (type === 'keydown') {
        /* Store existing listener function */
        const _listener = listener
        listener = (event) => {
          /* Simulate a 'down arrow' keypress if no address has been selected */
          const suggestionSelected = document.getElementsByClassName('pac-item-selected').length
          if (event.key === 'Enter' && !suggestionSelected) {
            const e = new KeyboardEvent('keydown', { 
              key: 'ArrowDown', 
              code: 'ArrowDown', 
              keyCode: 40, 
            })
            _listener.apply(input, [e])
          }
          _listener.apply(input, [event])
        }
      }
      _addEventListener.apply(input, [type, listener])
    }

    input.addEventListener = addEventListenerWrapper
  }

You should be good to go. Essentially, the function captures each keypress in the input field and if it's an enter, simulates instead a down-arrow keypress. It also stores and rebinds listeners and events to maintain all functionality of your Google Maps Autocomplete().

With thanks to earlier answers for much of this code, particular amirnissim and Alexander Schwarzman.


Here is a solution that does not make a geocoding request that may return an incorrect result: http://jsfiddle.net/amirnissim/2D6HW/

It simulates a down-arrow keypress whenever the user hits return inside the autocomplete field. The event is triggered before the return event so it simulates the user selecting the first suggestion using the keyboard.

Here is the code (tested on Chrome and Firefox) :

<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
<script>
    var pac_input = document.getElementById('searchTextField');

    (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 && !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);
</script>

I had the same issue when implementing autocomplete on a site I worked on recently. This is the solution I came up with:

$("input").focusin(function () {
    $(document).keypress(function (e) {
        if (e.which == 13) {
            var firstResult = $(".pac-container .pac-item:first").text();

            var geocoder = new google.maps.Geocoder();
            geocoder.geocode({"address":firstResult }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    var lat = results[0].geometry.location.lat(),
                        lng = results[0].geometry.location.lng(),
                        placeName = results[0].address_components[0].long_name,
                        latlng = new google.maps.LatLng(lat, lng);

                        $(".pac-container .pac-item:first").addClass("pac-selected");
                        $(".pac-container").css("display","none");
                        $("#searchTextField").val(firstResult);
                        $(".pac-container").css("visibility","hidden");

                    moveMarker(placeName, latlng);

                }
            });
        } else {
            $(".pac-container").css("visibility","visible");
        }

    });
});

http://jsfiddle.net/dodger/pbbhH/