Автозаполнение Google - введите, чтобы выбрать
У меня есть Автозапуск Google для текстового поля HTML-формы, и он отлично работает.
Однако, когда появляется список предложений, и вы используете стрелки для прокрутки и выбора с помощью ввода, он отправляет форму, хотя на ней все еще есть поля для заполнения. Если вы нажмете, чтобы выбрать предложение, оно отлично работает, но нажатие введите.
Как я могу это контролировать? Как я могу остановить ввод из представления формы и вместо этого выбрать выбор из автозаполнения?
Спасибо!
{S}
Ответы
Ответ 1
Вы можете использовать preventDefault
, чтобы остановить отправку формы при вводе, я использовал что-то вроде этого:
var input = document.getElementById('inputId');
google.maps.event.addDomListener(input, 'keydown', function(event) {
if (event.keyCode === 13) {
event.preventDefault();
}
});
Ответ 2
Использование обработки событий Google похоже на правильное решение, но оно не работает для меня. Это решение jQuery работает для меня:
$('#inputId').keydown(function (e) {
if (e.which == 13 && $('.pac-container:visible').length) return false;
});
.pac-container
- это div, который содержит совпадения автозаполнения. Идея заключается в том, что когда матчи видны, клавиша Enter просто выбирает активное совпадение. Но когда матчи скрыты (т.е. Место выбрано), он отправит форму.
Ответ 3
Я объединил первые два ответа от @sren и @mmalone, чтобы произвести это:
var input= document.getElementById('inputId');
google.maps.event.addDomListener(input, 'keydown', function(e) {
if (e.keyCode == 13 && $('.pac-container:visible').length) {
e.preventDefault();
}
});
отлично работает на странице. предотвращает отправку формы, когда видимый контейнер (.pac-container) отображается. Итак, теперь опция из раскрывающегося списка автозаполнения выбирается, когда пользователи нажимают клавишу ввода, и они должны снова нажать ее, чтобы отправить форму.
Моя основная причина для использования этого обходного пути заключается в том, что я обнаружил, что если форма отправляется сразу после выбора опции, с помощью клавиши ввода значения широты и долготы не передаются достаточно быстро в их скрытые элементы формы.
Все кредиты исходным ответам.
Ответ 4
Проблема, с которой я столкнулся с ответом @sren, заключалась в том, что она всегда блокирует событие отправки. Мне понравился ответ @mmalone, но он вел себя случайным образом, так как иногда, когда я нажимал ENTER
, чтобы выбрать местоположение, обработчик запускался после того, как контейнер скрыт. Итак, вот что я закончил делать
var location_being_changed,
input = document.getElementById("js-my-input"),
autocomplete = new google.maps.places.Autocomplete(input),
onPlaceChange = function () {
location_being_changed = false;
};
google.maps.event.addListener( this.autocomplete,
'place_changed',
onPlaceChange );
google.maps.event.addDomListener(input, 'keydown', function (e) {
if (e.keyCode === 13) {
if (location_being_changed) {
e.preventDefault();
e.stopPropagation();
}
} else {
// means the user is probably typing
location_being_changed = true;
}
});
// Form Submit Handler
$('.js-my-form').on('submit', function (e) {
e.preventDefault();
$('.js-display').text("Yay form got submitted");
});
<p class="js-display"></p>
<form class="js-my-form">
<input type="text" id="js-my-input" />
<button type="submit">Submit</button>
</form>
<!-- External Libraries -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
Ответ 5
Это работало для меня:
google.maps.event.addDomListener(input, 'keydown', e => {
// If it Enter
if (e.keyCode === 13) {
// Select all Google dropdown DOM nodes (can be multiple)
const googleDOMNodes = document.getElementsByClassName('pac-container');
// Check if any of them are visible (using ES6 here for conciseness)
const googleDOMNodeIsVisible = (
Array.from(googleDOMNodes).some(node => node.offsetParent !== null)
);
// If one is visible - preventDefault
if (googleDOMNodeIsVisible) e.preventDefault();
}
});
Может быть легко преобразован из ES6 в любой совместимый с браузером код.
Ответ 6
Я изменил код Alex, потому что он сломался в браузере. Это работает идеально для меня:
google.maps.event.addDomListener(
document.getElementById('YOUR_ELEMENT_ID'),
'keydown',
function(e) {
// If it Enter
if (e.keyCode === 13) {
// Select all Google dropdown DOM nodes (can be multiple)
const googleDOMNodes = document.getElementsByClassName('pac-container');
//If multiple nodes, prevent form submit.
if (googleDOMNodes.length > 0){
e.preventDefault();
}
//Remove Google drop down elements, so that future form submit requests work.
removeElementsByClass('pac-container');
}
}
);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
Ответ 7
Я пробовал приведенные выше короткие ответы, но они не работали для меня, и длинные ответы, которые я не хотел попробовать, поэтому я создал следующий код, который очень хорошо работал у меня. См. демонстрацию
Предположим, что это ваша форма:
<form action="" method="">
<input type="text" name="place" id="google-places-searchbox" placeholder="Enter place name"><br><br>
<input type="text" name="field-1" placeholder="Field 1"><br><br>
<input type="text" name="field-2" placeholder="Field 2"><br><br>
<button type="submit">Submit</button>
</form>
Тогда следующий код javascript решит проблему:
var placesSearchbox = $("#google-places-searchbox");
placesSearchbox.on("focus blur", function() {
$(this).closest("form").toggleClass('prevent_submit');
});
placesSearchbox.closest("form").on("submit", function(e) {
if (placesSearchbox.closest("form").hasClass('prevent_submit')) {
e.preventDefault();
return false;
}
});
И вот как выглядит полный код на странице HTML (обратите внимание, что вам нужно заменить YOUR_API_KEY
на ваш ключ google api):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Prevent form submission when choosing a place from google places autocomplete searchbox</title>
</head>
<body>
<form action="" method="">
<input type="text" name="place" id="google-places-searchbox" placeholder="Enter place name"><br><br>
<input type="text" name="field-1" placeholder="Field 1"><br><br>
<input type="text" name="field-2" placeholder="Field 2"><br><br>
<button type="submit">Submit</button>
</form>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- Google Maps -->
<!-- Note that you need to replace the next YOUR_API_KEY with your api key -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"
async defer></script>
<script>
var input = document.getElementById("google-places-searchbox");
var searchBox = new google.maps.places.SearchBox(input);
var placesSearchbox = $("#google-places-searchbox");
placesSearchbox.on("focus blur", function() {
$(this).closest("form").toggleClass('prevent_submit');
});
placesSearchbox.closest("form").on("submit", function(e) {
if (placesSearchbox.closest("form").hasClass('prevent_submit')) {
e.preventDefault();
return false;
}
});
</script>
</body>
</html>