afithings
afithings

Reputation: 691

Google Autocomplete Places API not triggering event on change via TAB

Per the Google Autocomplete Places API documentation, the getPlace() call should return a Places object with all the location data, or, if that place doesn't exist (i.e. - the user ignored the suggestions), it should return a stub with just the name element of the Places object filled in. However, it only does this latter operation when the user hits ENTER, not if they TAB out of the field.

I've tried looking at the change event, the keyup, keydown events. I've tried triggering a keydown event with keycode 13 on blur, etc. etc. Nothing seems to work.

Has anyone overcome this issue? It seems pretty obvious that a user would tab through a form, and there's always the possibility they ignore the suggestions.

Upvotes: 4

Views: 7510

Answers (3)

MrUpsidown
MrUpsidown

Reputation: 22497

pac-input being your place search input, you can do the following:

// Trigger search on blur
document.getElementById('pac-input').onblur = function () {

    google.maps.event.trigger(this, 'focus', {});
    google.maps.event.trigger(this, 'keydown', {
        keyCode: 13
    });
};

Or with a google maps event listener:

// Trigger search on blur
google.maps.event.addDomListener(document.getElementById("pac-input"), 'blur', function() {

    google.maps.event.trigger(this, 'focus', {});
    google.maps.event.trigger(this, 'keydown', {
        keyCode: 13
    });
});

Edit: As mentioned in the comments, this messes up with the "normal behavior" of a user selecting a place by mouse click.

Below is a complete example using pure Javascript. For a (simpler) jQuery solution, look at @ChrisSnyder's answer.

function initialize() {

  var ac = new google.maps.places.Autocomplete(
    (document.getElementById('autocomplete')), {
      types: ['geocode']
    });

  ac.addListener('place_changed', function() {

    var place = ac.getPlace();

    if (!place.geometry) {

      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      console.log("No details available for input: '" + place.name + "'");
      return;
    }

    console.log("You selected: '" + place.formatted_address + "'");
  });

  // Trigger search on blur
  google.maps.event.addDomListener(document.getElementById("autocomplete"), 'blur', function() {

    // Find the pac-container element
    var pacContainer = nextByClass(this, 'pac-container');

    // Check if we are hovering on one of the pac-items
    // :hover propagates to parent element so we only need to check it on the pac-container
    // We trigger the focus and keydown only if :hover is false otherwise it will interfere with a place selection via mouse click
    if (pacContainer.matches(':hover') === false) {

      google.maps.event.trigger(this, 'focus', {});
      google.maps.event.trigger(this, 'keydown', {
        keyCode: 13
      });
    }

  });
}

function hasClass(elem, cls) {
  var str = " " + elem.className + " ";
  var testCls = " " + cls + " ";
  return (str.indexOf(testCls) != -1);
}

function nextByClass(node, cls) {
  while (node = node.nextSibling) {
    if (hasClass(node, cls)) {
      return node;
    }
  }
  return null;
}
#autocomplete {
  width: 300px;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" async defer></script>
<input id="autocomplete" placeholder="Enter your address" type="text"></input>

Upvotes: 9

Chris Snyder
Chris Snyder

Reputation: 86

The following expands on @MrUpsidown's solution but tries to avoid messing with the user when they click on an item in the dropdown as mentioned by @Jkk.jonah

// Trigger search on blur
google.maps.event.addDomListener(document.getElementById("pac-input"), 'blur', function() {
  if (jQuery('.pac-item:hover').length === 0 ) {
    google.maps.event.trigger(this, 'focus', {});
    google.maps.event.trigger(this, 'keydown', {
        keyCode: 13
    });
  } 
});

Upvotes: 5

Apparently something changed and the above code is not working the last days, and the following exception appeared in the console

 undefined is not an object (evaluating 'a.handled=!0')

You need to add an empty object on the trigger of the focus event

var inputSearch = document.getElementById('pac-input');

google.maps.event.trigger(inputSearch, 'focus', {})
google.maps.event.trigger(inputSearch, 'keydown', {
    keyCode: 13
});

Upvotes: 2

Related Questions