2

I used to use the following code to catch users' Enter key event and automatically pick the first result from the Autocomplete results (pac-items) if users haven't selected any of them (i.e., there is no pac-item marked as pac-item-selected).

var input = document.getElementById('pac-input')
var autocomplete = new google.maps.places.Autocomplete(input)

google.maps.event.addDomListener(input, 'keypress', function(e) {
    if (e.keyCode===13 && !e.triggered) {
        var suggestion_selected = document.querySelectorAll('.pac-item-selected').length > 0
        if (!isLatLngInInputBox && !suggestion_selected) {
            google.maps.event.trigger(this,'keydown',{keyCode:40})
            google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true})
        }
    }
})

However, started from Google Maps JavaScript API v3.35, I would get an error like Uncaught TypeError: a.stopPropagation is not a function raised in the line of google.maps.event.trigger(this,'keydown',{keyCode:40}).

As a result, I checked the documentation and noticed that trigger method of google.maps.event has changed. The third argument is now stated as eventArgs instead of var_args.

I tried to figure out how to adapt to it and modified the code like:

google.maps.event.addDomListener(input, 'keypress', function(e) {
    console.log(e.key)
    if (e.key==="Enter" && !e.triggered) {
        var suggestion_selected = document.querySelectorAll('.pac-item-selected').length > 0
        if (!isLatLngInInputBox && !suggestion_selected) {
            google.maps.event.trigger(this,'keydown',{key:"ArrowDown"})
            google.maps.event.trigger(this,'keydown',{key:"Enter",triggered:true})
        }
    }
})

Although the Enter key can be captured perfectly, the ArrowDown key does not work as intended.

In fact, I can capture the ArrowDown key with console.log(e.key), but nothing really happens. Also, console.log(e.key) does not catch anything when I press the ArrowDown key on my keyboard, which makes me so confused.

Does anyone encounter similar problem? Thanks for any suggestion!

Clifford Yen
  • 23
  • 1
  • 6

1 Answers1

6

Use new Event() to create proper event object as third parameter and also keydown instead of keypress in your addDomListener

var input = document.getElementById('pac-input')
var autocomplete = new google.maps.places.Autocomplete(input)
google.maps.event.addDomListener(input, 'keydown', function(e) {
  var suggestion_selected = document.querySelectorAll('.pac-item-selected').length > 0
  if (suggestion_selected) {
    console.log(document.querySelectorAll('.pac-item-selected'));
  } else {
    if (e.key === "Enter" && !e.triggered) {
      var ex1 = new Event('keydown');
      ex1.code = "ArrowDown";
      ex1.key = "ArrowDown";
      ex1.keyCode = 40;
      google.maps.event.trigger(this, 'keydown', ex1);

      var ex2 = new Event('keydown');
      ex2.code = "Enter";
      ex2.key = "Enter";
      ex2.keyCode = 13;
      ex2.triggered = true;
      google.maps.event.trigger(this, 'keydown', ex2);
    }
  }
});

Edit:

I have a working fiddle here https://jsfiddle.net/ergec/e6wsdb85/

Ergec
  • 11,608
  • 7
  • 52
  • 62
  • Thanks for your advice. In fact I have tried to change `keypress` to `keydown` with no luck. The behavior is just the same. – Clifford Yen Dec 22 '18 at 04:39
  • @CliffordYen I tested my code captures all keys. Here is the fiddle https://jsfiddle.net/ergec/e6wsdb85/ – Ergec Dec 22 '18 at 13:18
  • Impressive! Why using `keydown` instead of `keypress` makes difference? Unfortunately, although it can capture ArrowDown key, it still can't select the first result from Google Maps Autocomplete results. – Clifford Yen Dec 22 '18 at 17:12
  • I can select all results including the first one. Can you replicate your problem on jsfiddle so i can check? – Ergec Dec 22 '18 at 18:05
  • Sorry Ergec, I should say "it still can't select the first result automatically if users hit Enter without selecting any result." I know I can select any result from the Autocomplete results. For the jsfiddle, it seems like I cannot make Autocomplete work without providing the Google Maps API key. So I am sorry, it might be hard to show the problem exactly. – Clifford Yen Dec 23 '18 at 03:50
  • @CliffordYen I think (and hope) I understand your problem now. Please check my fiddle again, I updated it. – Ergec Dec 23 '18 at 11:46
  • Thank you Ergec! Although there are some problems of your updated code, the idea of using `new Event('keydown')` makes the difference! You can improve the code by (1) replace the DOM listener from `keydown` back to `keypress`, or it would cause some trouble typing in languages other than English. I would explain later. (2) turns out only `keyCode` is effective. `key` and `code` are redundant. I also want to ask how did you do to make the Autocomplete function works on jsfiddle without providing the GMaps API key? – Clifford Yen Dec 23 '18 at 15:33
  • The explanation of using `keypress` as the DOM listener: When users type in languages like Traditional Chinese, every character would be in an undetermined state with an underscore before hitting the Enter key. In this state, every character can be changed to another character that has a similar pronunciation. After hitting Enter key, that character would be determined and cannot be changed. If you use `keydown` in this case, the keyword that a user types would be kept and follow the first result of Autocomplete in the search bar after hitting Enter, and make the inquiry failed. – Clifford Yen Dec 23 '18 at 15:45
  • @CliffordYen I did use an API key. Just a different one that I use only on jsfiddle. – Ergec Dec 23 '18 at 16:54
  • @CliffordYen also if my solution hepled you to solve your problems it would be great if you accept my answer. – Ergec Dec 23 '18 at 17:03
  • Sure. Thank you! – Clifford Yen Dec 24 '18 at 00:06