it-swarm.dev

Preenchimento Automático do Google Places - Escolha o primeiro resultado na tecla Enter?

Estou usando um preenchimento automático do Google Places e simplesmente quero que ele selecione o item principal na lista de resultados quando a tecla Enter for pressionada no campo de formulário e houver sugestões. Eu sei que isso foi perguntado antes:

Autocompletar Google Places Places API V3 - selecione a primeira opção ao entrar

Autocomplete do Google maps Places API V3 - selecione a primeira opção ao entrar (e mantenha-a assim)

Mas as respostas nessas perguntas não parecem realmente funcionar ou elas abordam funcionalidades adicionais específicas.

Também parece que algo como o seguinte deve funcionar (mas não funciona):

$("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
    }
  }
});

Qualquer sugestão seria muito apreciada!

28
NChase

Eu li as muitas respostas desta questão, e das respostas das perguntas ligadas tantas vezes, antes de achar que a melhor resposta é esta (Nota: infelizmente, não é a resposta aceita!).

Modifiquei 2 ou 3 linhas para transformá-lo em uma função pronta para uso que você pode copiar/colar em seu código e aplicar a muitos elementos input, se necessário. Aqui 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);
...
9
Basj

Estou repostando minha resposta de Google maps Autofechamento do Places API V3 - selecione a primeira opção ao entrar :

Parece que há uma solução muito melhor e mais limpa: usar google.maps.places.SearchBox em vez de google.maps.places.Autocomplete. Um código é quase o mesmo, apenas obtendo o primeiro de vários lugares. Ao pressionar Enter, a lista correta é retornada - assim, ele é executado fora da caixa e não há necessidade de hacks.

Veja a página HTML de exemplo:

http://rawgithub.com/klokan/8408394/raw/5ab795fb36c67ad73c215269f61c7648633ae53e/places-enter-first-item.html

O fragmento de código relevante é:

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);
  }
});

O código-fonte completo do exemplo está em: https://Gist.github.com/klokan/8408394

9
Klokan Technologies

No meu site para conseguir essa mesma funcionalidade eu precisei do plugin jQuery simulate ( https://github.com/jquery/jquery-simulate ) e então anexei o 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 });
        }
    });
});

O plugin irá simular a ação de pressionar a tecla DOWN e depois ENTER, ENTER em si não funciona e não consegui encontrar outra forma de selecionar a primeira opção.

Espero que isto ajude

4
Mangiucugna

Solução de trabalho que escuta se o usuário começou a navegar pela lista com o teclado em vez de acionar a navegação falsa a cada vez

https://codepen.io/callam/pen/RgzxZB

Aqui estão os bits 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;
    }

});
4
Callam

Isso é o que eu fiz e 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;

    }
  }

}
2
Fronto

Se você estiver usando o Angular 2,4, 5 e 6, por favor, encontrar a resposta neste link abaixo

Angular 6, o AGM seleciona o primeiro endereço no preenchimento automático do google

Angular AGM autocomplete first address sugestão

0
saravana va

Essa é a maneira mais fácil que me resolveu:

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
  });
}
0
Fillype Farias