Reputation: 407
I'm using Google Places Autocomplete and Google Maps api. In my js I wrapped the listener for the autocomplete in order to simulate a combination of "down arrow" and "enter" events if there is no autocomplete result selected.
See the following snippet:
var pac_input = document.getElementById('locatorPlaceSearch');
var orig_listener;
(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") {
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]);
mapsListener = listener;
}
input.addEventListener = addEventListenerWrapper;
input.attachEvent = addEventListenerWrapper;
})(pac_input);
autocomplete = new google.maps.places.Autocomplete(pac_input,
{
componentRestrictions: { country: $('#hdnLocatorPlace').val() },
types: ['geocode']
});
Now I have a "Search" button, and I want to trigger a "down arrow" and "enter" as well. I tried this code but it's not firing the keydown event on the listener:
$('#searchAP').off('click').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
setTimeout(function() {
$('#locatorPlaceSearch').focus();
$('#locatorPlaceSearch').click();
setTimeout(function() {
var sev = $.Event("keydown", {
keyCode: 13,
which: 13
});
//mapsListener.apply($('#locatorPlaceSearch'), [sev]);
$('#locatorPlaceSearch').trigger(sev);
},1000);
}, 1000);
//$('#locatorPlaceSearch').trigger(sev);
});
What's wrong with this code?
Upvotes: 1
Views: 3615
Reputation: 117354
I can't tell you exactly what's going on there, as it seems the event will not be triggered at all(at least your listener will not be called).
You may trigger the event by using the native DOM-method (dispatchEvent
):
google.maps.event.addDomListener(window, 'load', function() {
var pac_input = document.getElementById('locatorPlaceSearch');
var orig_listener;
(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") {
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]);
mapsListener = listener;
}
input.addEventListener = addEventListenerWrapper;
input.attachEvent = addEventListenerWrapper;
})(pac_input);
autocomplete = new google.maps.places.Autocomplete(pac_input, {
componentRestrictions: {
country: $('#hdnLocatorPlace').val()
},
types: ['geocode']
});
$('#searchAP').off('click').on('click', function(e) {
var keydown = document.createEvent('HTMLEvents');
keydown.initEvent("keydown", true, false);
Object.defineProperty(keydown, 'keyCode', {
get: function() {
return 13;
}
});
Object.defineProperty(keydown, 'which', {
get: function() {
return 13;
}
});
pac_input.dispatchEvent(keydown);
});
});
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places"></script>
<input id="locatorPlaceSearch">
<input type="submit" id="searchAP">
<input type="hidden" id="hdnLocatorPlace" value="de">
Another solution, using the event-wrapper of the maps-API:
google.maps.event.addDomListener(window, 'load', function() {
(function(input, opts, nodes) {
var ac = new google.maps.places.Autocomplete(input, opts);
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
})
}
});
for (var n = 0; n < nodes.length; ++n) {
google.maps.event.addDomListener(nodes[n].n, nodes[n].e, function(e) {
google.maps.event.trigger(input, 'keydown', {
keyCode: 13
})
});
}
}
(
document.getElementById('locatorPlaceSearch'), {
componentRestrictions: {
country: document.getElementById('hdnLocatorPlace').value
},
types: ['geocode']
}, [{
n: document.getElementById('searchAP'),
e: 'click'
}]
));
});
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places"></script>
<input id="locatorPlaceSearch">
<input type="submit" id="searchAP">
<input type="hidden" id="hdnLocatorPlace" value="de">
Upvotes: 5