Я хочу предотвратить смещение фокуса из поля ввода, когда пользователь использует мышь, чтобы выбрать предложение для города / штата, предоставленное API мест Google. Таким образом, когда пользователь нажимает Tab, фокус может корректно сместиться к следующему очевидному полю ввода. Но я не могу предотвратить событие onblur, когда пользователь выбирает (используя мышь) значение, предложенное функцией автозаполнения Google в его местах API. Эта проблема не возникает при выборе значения с помощью клавиатуры. Вот мой код - спасибо за помощь в решении этой проблемы, так как я не очень знаком с манипуляциями с кодом API Google.
Вот мой HTML-код:
<div class="col-md-4 col-sm-12 col-xs-12">
<div class="form-group">
<input gp-gac="{ types: ['(cities)'], componentRestrictions: { country: 'US' }}" class="form-control"
ng-model="home_ctrl.location"
gp-components="{ locality: 'long_name', administrative_area_level_1: 'short_name' }"
gp-callback="home_ctrl.gpSearchCb(result, place)"
vs-city="home_ctrl.city"
vs-state="home_ctrl.state"
placeholder="City, State"
id="txtCity">
</div>
</div>
А вот код javascript, который вызывает API мест Google:
(function() {
'use strict'
var gpGac = function() {
return {
restrict: 'A',
require: '?ngModel',
scope: {
gpGac: '=',
gpOptions: '=?',
gpComponents: '=?',
gpCity: '=?',
gpState: '=?',
gpZip: '=?',
gpCallback: '&?',
},
link: {
pre: function(scope, element, attributes, modelCtrl) {
var autocomplete = new google.maps.places.Autocomplete(
element[0],
scope.gpGac,
),
options = scope.gpOptions || {submitOnEnter: true},
itemSelected
scope.gpComponents = scope.gpComponents || {
locality: 'long_name',
sublocality: 'long_name',
administrative_area_level_1: 'short_name',
neighborhood: 'long_name',
postal_code: 'short_name',
}
console.log(
'scope.gpComponents: ' + JSON.stringify(scope.gpComponents),
)
var autocompleteListener = autocomplete.addListener(
'place_changed',
function() {
var place = this.getPlace(),
result = {}
if (place.address_components) {
place.address_components.forEach(function(addrComp) {
addrComp.types.forEach(function(type) {
if (scope.gpComponents && scope.gpComponents[type]) {
result[type] = addrComp[scope.gpComponents[type]]
}
})
})
scope.gpState = result.administrative_area_level_1
if (result.locality && isOnDisplay(result.locality)) {
scope.gpCity = result.city = result.locality
}
if (result.sublocality && isOnDisplay(result.sublocality)) {
scope.gpCity = result.city = result.sublocality
}
if (result.neighborhood && isOnDisplay(result.neighborhood)) {
scope.gpCity = result.city = result.neighborhood
}
scope.gpZip = result.postal_code
// check if it's displayed on input
function isOnDisplay(addrComp) {
return place.formatted_address.search(addrComp) > -1
}
scope.$apply(function() {
if (modelCtrl) {
modelCtrl.$setViewValue(
result[options.display]
? result[options.display]
: place.formatted_address,
)
} else {
element.val(
result[options.display]
? result[options.display]
: place.formatted_address,
)
}
if (scope.gpCallback) {
scope.gpCallback({result: result, place: place})
}
if (modelCtrl) {
modelCtrl.$render()
}
})
}
},
)
var enterKeydownListener = google.maps.event.addDomListener(
element[0],
'keydown',
function(e) {
if (e.keyCode === 13) {
if (!options.submitOnEnter && itemSelected) {
e.preventDefault()
itemSelected = !itemSelected
}
}
},
)
var enterKeyupListener = google.maps.event.addDomListener(
element[0],
'keyup',
function(e) {
if (e.keyCode === 38 || e.keyCode === 40) {
itemSelected = angular
.element(document)
.find('.pac-item-selected').length
}
},
)
element.on('$destroy', function() {
autocompleteListener.remove()
enterKeydownListener.remove()
enterKeyupListener.remove()
autocomplete.unbindAll()
})
},
post: function(scope, element, attributes, modelCtrl) {},
},
}
}
angular.module('routerApp').directive('gpGac', ['$rootScope', gpGac])
})()