Автозаполнение Google Адресов - нажмите первый результат на размытие

Я использую автозаполнение Google Адресов, и я просто хочу, чтобы оно вызывало событие клика по верхнему элементу в списке результатов, когда происходит событие размытия в поле формы и существуют предложения.

var pac_input = document.getElementById ('pick-auto');

                (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" || type == "blur") {
                      var orig_listener = listener;
                      listener = function(event) {
                        var suggestion_selected = $(".pac-item-selected").length > 0;
                        var keyCode = event.keyCode || event.which;
                        if ((keyCode === 13 || keyCode === 9) && !suggestion_selected) {
                          var simulated_downarrow = $.Event("keydown", {
                            keyCode: 40,
                            which: 40
                          });
                          orig_listener.apply(input, [simulated_downarrow]);
                        } else if(event.type === 'blur') {
                            pac_input.value =
                             $(".pac-container .pac-item:first-child").text();
                            // $(".pac-container").delegate(".pac-item:first-child","click",function(){
                            //  console.log("success");
                            // });

                            $(".pac-container .pac-item:first-child").bind('click',function(){
                                console.log("click");
                            });

                        }
                        orig_listener.apply(input, [event]);
                      };
                    }

                    // add the modified listener
                    _addEventListener.apply(input, [type, listener]);
                  }

                  if (input.addEventListener)
                    input.addEventListener = addEventListenerWrapper;
                  else if (input.attachEvent)
                    input.attachEvent = addEventListenerWrapper;

                })(pac_input);


                $(function() {
                  var autocomplete = new google.maps.places.Autocomplete(pac_input);
                });

2 ответа

Решение

Попробуй это:

DEmo: http://jsfiddle.net/q7L8bawe/

Добавить это событие:

$("#pick-auto").blur(function (e) {
        if (e.which == 13) {
            var firstResult = $(".pac-container .pac-item:first").text();

            var geocoder = new google.maps.Geocoder();
            geocoder.geocode({"address":firstResult }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    var lat = results[0].geometry.location.lat(),
                        lng = results[0].geometry.location.lng(),
                        placeName = results[0].address_components[0].long_name,
                        latlng = new google.maps.LatLng(lat, lng);

                        $(".pac-container .pac-item:first").addClass("pac-selected");
                        $(".pac-container").css("display","none");
                        $("#pick-auto").val(firstResult);
                        $(".pac-container").css("visibility","hidden");

                }
            });
        } else {
            $(".pac-container").css("visibility","visible");
        }

    });

Я сделал это в своем проекте:

    function initAutocomplete() {
        autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'), {types: ['geocode']});
        autocomplete.setFields(['address_component']);
        // "standard" place_changed event
        autocomplete.addListener('place_changed', fillInAddress);
        // custom blur event
        $("#autocomplete").on('blur', function () {
            var $hover = $(".pac-container .pac-item:hover");
            // if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place
            if ($hover.length === 0) {
                var firstResult = $(".pac-container .pac-item:first").text();
                var geocoder = new google.maps.Geocoder();
                geocoder.geocode({
                    address: firstResult
                }, function (results, status) {
                    if (status === google.maps.GeocoderStatus.OK) {
                        fillInAddress(results[0]);
                    }
                });
            }
        });
    }

    function fillInAddress(place) {
        if (!place) {
            place = autocomplete.getPlace();
        }
        if (place && place.address_components) {
            // ... do what you need with the place
        }
    }

В случае размытия, после большого количества потраченного времени я понял, что размытие выполняется раньше всего (например, имитация нажатия клавиш). Также,

pac_input.value = $(".pac-container .pac-item:first-child").text();

$(".pac-container .pac-item:first-child").bind('click',function(){
  console.log("click");
});

это связывает текстовое значение, которое ужасно для автозаполнения. В качестве альтернативы я сделал это в другой части (размытие):

} else if (event.type == 'blur' && $(".pac-item").length > 0) {
                                var search = $('.pac-container:eq( '+$scope.$index+' ) .pac-item:first-child').text();
                                var autocompleteService = new google.maps.places.AutocompleteService();
                                autocompleteService.getPlacePredictions({
                                    'input': search,
                                    'offset': search.length,
                                    'componentRestrictions': { 'country': 'ar' }
                                }, function listentoresult(list, status) {
                                    if (list == null || list.length == 0) {
                                       //error!
                                    } else {
                                        //do what u want with the first autocomplete, it is the first result that the service will give you. If you want the same result with places, you must ask for the placesServices from googleapi
                                    }
                                });
                            }

НОТА:

$ ('. pac-container: eq (' + $ scope. $ index + ').pac-item: first-child'). text ()

Я использую это, потому что у меня есть несколько автозаполнений, и есть много pac-контейнеров, но если у вас есть только один,

$ ('. pac-container.pac-item: first-child'). text ()

должно хватить.

С этим ответом я создал код, чтобы выбрать первый элемент при размытии, а также при входе:

_addSelectFirstEvents() {
  const autoSelectFirstEntry = (e) => {
    if (e.type === 'keydown' && e.keyCode === 13) event.preventDefault()

    const isSuggestionSelected = document.querySelectorAll('.pac-item-selected').length > 0
    if (
      !isSuggestionSelected &&
      ((e.keyCode === 13 && !e.triggered) || e.type === 'blur')
    ) {
      let arrowDownKeyEvent = new KeyboardEvent('keydown', {
        bubbles: true,
        cancelable: true,
        key: 'Down',
        code: 'Down',
        keyCode: 40,
        which: 40,
      })
      google.maps.event.trigger(e.target, 'keydown', arrowDownKeyEvent)

      const enterKeyEvent = new KeyboardEvent('keydown', {
        bubbles: true,
        cancelable: true,
        key: 'Enter',
        code: 'Enter',
        keyCode: 13,
        which: 13,
        triggered: true,
      })
      google.maps.event.trigger(e.target, 'keydown', enterKeyEvent)
    }
  }

  google.maps.event.addDomListener(this.input, 'blur', autoSelectFirstEntry)
  google.maps.event.addDomListener(this.input, 'keydown', autoSelectFirstEntry)
}

Другие вопросы по тегам