javascript - example - Autocompletar de Google Places: ¿elige el primer resultado en la tecla Entrar?
input address google maps (9)
Estoy usando un autocompletado de Google Places y simplemente quiero que seleccione el elemento superior en la lista de resultados cuando se presiona la tecla Intro en el campo de formulario y existen sugerencias. Sé que esto se ha preguntado antes:
Google Maps Places API V3 autocompletar: seleccione la primera opción al ingresar
Pero las respuestas en esas preguntas no parecen funcionar en realidad, o abordan funciones adicionales específicas.
También parece que algo como lo siguiente debería funcionar (pero no es así):
$("input#autocomplete").keydown(function(e) {
if (e.which == 13) {
//if there are suggestions...
if ($(".pac-container .pac-item").length) {
//click on the first item in the list or simulate a down arrow key event
//it does get this far, but I can''t find a way to actually select the item
$(".pac-container .pac-item:first").click();
} else {
//there are no suggestions
}
}
});
¡Cualquier sugerencia sería muy apreciada!
Coloque el elemento de entrada fuera del elemento de formulario. Complete el formulario con javascript.
document.getElementById("adress").value = place.formatted_address;
En mi sitio para lograr esta misma funcionalidad, necesitaba el plugin de jQuery simulate ( https://github.com/jquery/jquery-simulate ) y luego adjunte el evento:
$("input#autocomplete").focusin(function () {
$(document).keypress(function (e) {
if (e.which == 13) {
$("input#autocomplete").trigger(''focus'');
$("input#autocomplete").simulate(''keydown'', { keyCode: $.ui.keyCode.DOWN } ).simulate(''keydown'', { keyCode: $.ui.keyCode.ENTER });
}
});
});
El complemento simulará la acción de presionar la tecla ABAJO y luego ENTER, ENTER no funciona y no pude encontrar otra manera de seleccionar la primera opción.
Espero que esto ayude
Esta es la forma más fácil que me solucionó:
autocomplete.addListener(''place_changed'', function() {
if(event.keyCode == 13 || event.keyCode == 9) { // detect the enter key
var firstValue = $(".pac-container .pac-item:first").text(); // assign to this variable the first string from the autocomplete dropdown
}
$(''#search-address'').val(firstValue); // add this string to input
console.log(firstValue); // display the string on your browser console to check what it is
//(...) add the rest of your code here
});
}
Esto es lo que hice y funciona:
HTML:
<input name="location" id="autocomplete" autocomplete="off" type="text" class="textbx" placeholder="Enter Destination" required>
googleautocompletecustomized.js:
function initialize() {
// Create the autocomplete object, restricting the search
// to geographical location types.
if($(''#autocomplete'').length){
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById(''autocomplete'')),
{
types: [''(regions)''],
componentRestrictions: {country: "in"}
});
google.maps.event.addListener(autocomplete, ''place_changed'', function() {
$(''#autocomplete'').closest(''form'').data(''changed'', true);
fillInAddress();
});
}
//select first result
$(''#autocomplete'').keydown(function (e) {
if (e.keyCode == 13 || e.keyCode == 9) {
$(e.target).blur();
if($(".pac-container .pac-item:first span:eq(3)").text() == "")
var firstResult = $(".pac-container .pac-item:first .pac-item-query").text();
else
var firstResult = $(".pac-container .pac-item:first .pac-item-query").text() + ", " + $(".pac-container .pac-item:first span:eq(3)").text();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"address":firstResult }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
placeName = results[0];
e.target.value = firstResult;
fillInAddress(placeName);
$(''#datetimepicker1 .input-group-addon'').click();
}
});
}
});
}
// [START region_fillform]
function fillInAddress(place) {
// Get the place details from the autocomplete object.
if(!place)
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '''';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
Estoy volviendo a publicar mi respuesta de Google Maps Places API V3 autocompletar: seleccione la primera opción al ingresar :
Parece que hay una solución mucho mejor y más limpia: utilizar google.maps.places.SearchBox
lugar de google.maps.places.Autocomplete
. Un código es casi lo mismo, simplemente obtener el primero de múltiples lugares. Al presionar Enter, se devuelve la lista correcta, por lo que se ejecuta fuera de la caja y no hay necesidad de hacks.
Vea la página HTML de ejemplo:
El fragmento de código relevante es:
var searchBox = new google.maps.places.SearchBox(document.getElementById(''searchinput''));
google.maps.event.addListener(searchBox, ''places_changed'', function() {
var place = searchBox.getPlaces()[0];
if (!place.geometry) return;
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(16);
}
});
El código fuente completo del ejemplo está en: https://gist.github.com/klokan/8408394
He leído muchas veces las respuestas de esta pregunta y de las preguntas enlazadas, antes de encontrar que la mejor respuesta es esta (Nota: lamentablemente, ¡no es la respuesta aceptada!).
He modificado 2 o 3 líneas para convertirla en una función lista para usar que puedes copiar / pegar en tu código y aplicar a muchos elementos de input
si es necesario. Aquí está:
var selectFirstOnEnter = function(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]); // add the modified listener
}
if (input.addEventListener) { input.addEventListener = addEventListenerWrapper; } else if (input.attachEvent) { input.attachEvent = addEventListenerWrapper; }
}
Uso:
selectFirstOnEnter(input1);
selectFirstOnEnter(input2);
...
Hice un poco de trabajo alrededor de esto y ahora puedo forzar la selección de la primera opción desde google placces usando angular js y el módulo angular Autocompletar.
Gracias a kuhnza
mi código
<form method="get" ng-app="StarterApp" ng-controller="AppCtrl" action="searchresults.html" id="target" autocomplete="off">
<br/>
<div class="row">
<div class="col-md-4"><input class="form-control" tabindex="1" autofocus g-places-autocomplete force-selection="true" ng-model="user.fromPlace" placeholder="From Place" autocomplete="off" required>
</div>
<div class="col-md-4"><input class="form-control" tabindex="2" g-places-autocomplete force-selection="true" placeholder="To Place" autocomplete="off" ng-model="user.toPlace" required>
</div>
<div class="col-md-4"> <input class="btn btn-primary" type="submit" value="submit"></div></div><br /><br/>
<input class="form-control" style="width:40%" type="text" name="sourceAddressLat" placeholder="From Place Lat" id="fromLat">
<input class="form-control" style="width:40%"type="text" name="sourceAddressLang" placeholder="From Place Long" id="fromLong">
<input class="form-control" style="width:40%"type="text" name="sourceAddress" placeholder="From Place City" id="fromCity">
<input class="form-control" style="width:40%"type="text" name="destinationAddressLat" placeholder="To Place Lat" id="toLat">
<input class="form-control" style="width:40%"type="text" name="destinationAddressLang" placeholder="To Place Long"id="toLong">
<input class="form-control" style="width:40%"type="text" name="destinationAddress"placeholder="To Place City" id="toCity">
</form>
Aquí hay un Plunker
Gracias.
Si está utilizando Angular 2,4, 5 y 6 , encuentre la respuesta en este enlace a continuación
Angular 6, AGM selecciona la primera dirección en google autocomplete
Angular AGM autocompletar la primera sugerencia de dirección
Solución de trabajo que escucha si el usuario ha comenzado a navegar por la lista con el teclado en lugar de activar la navegación falsa cada vez
https://codepen.io/callam/pen/RgzxZB
Aquí están los pedazos importantes
// search input
const searchInput = document.getElementById(''js-search-input'');
// Google Maps autocomplete
const autocomplete = new google.maps.places.Autocomplete(searchInput);
// Has user pressed the down key to navigate autocomplete options?
let hasDownBeenPressed = false;
// Listener outside to stop nested loop returning odd results
searchInput.addEventListener(''keydown'', (e) => {
if (e.keyCode === 40) {
hasDownBeenPressed = true;
}
});
// GoogleMaps API custom eventlistener method
google.maps.event.addDomListener(searchInput, ''keydown'', (e) => {
// Maps API e.stopPropagation();
e.cancelBubble = true;
// If enter key, or tab key
if (e.keyCode === 13 || e.keyCode === 9) {
// If user isn''t navigating using arrows and this hasn''t ran yet
if (!hasDownBeenPressed && !e.hasRanOnce) {
google.maps.event.trigger(e.target, ''keydown'', {
keyCode: 40,
hasRanOnce: true,
});
}
}
});
// Clear the input on focus, reset hasDownBeenPressed
searchInput.addEventListener(''focus'', () => {
hasDownBeenPressed = false;
searchInput.value = '''';
});
// place_changed GoogleMaps listener when we do submit
google.maps.event.addListener(autocomplete, ''place_changed'', function() {
// Get the place info from the autocomplete Api
const place = autocomplete.getPlace();
//If we can find the place lets go to it
if (typeof place.address_components !== ''undefined'') {
// reset hasDownBeenPressed in case they don''t unfocus
hasDownBeenPressed = false;
}
});