Google 자동 완성-선택하려면 입력하세요.


81

내가 가진 구글 자동 완성은 HTML 형식의 텍스트 필드에 대한 설정, 그것은 완벽하게 작동합니다.

그러나 제안 목록이 표시되고 화살표를 사용하여 스크롤하고 Enter를 사용하여 선택하면 양식이 제출되지만 입력 할 상자가 여전히 있습니다. 제안을 클릭하여 선택하면 제대로 작동하지만 Enter 키를 누르면 제출됩니다. .

어떻게 제어 할 수 있습니까? Enter가 양식 제출을 중지하고 대신 자동 완성에서 제안을 선택하려면 어떻게해야합니까?

감사! {에스}

답변:


110

당신은 사용할 수 있습니다 preventDefault,이 같은 것을 사용 맞았다 입력 할 때 제출되는 양식을 중지 :

  var input = document.getElementById('inputId');
  google.maps.event.addDomListener(input, 'keydown', function(event) { 
    if (event.keyCode === 13) { 
        event.preventDefault(); 
    }
  }); 

2
이것은 항상 필드에서 제출을 취소합니다. 사용자가 자동 ​​완성 옵션을 선택하기 위해 인트로를 누른 경우 제출을 취소하는 데만 필요합니다.
A. Matías Quezada 2013 년

1
보석처럼 작동합니다. 아래로 누르고 Enter를 사용하여 목록에서 자동 완성 옵션을 선택해도 더 이상 양식이 제출되지 않습니다.
Eric L.

이것은 해결책 이라기보다 더 패턴이없는 것입니다. onSubmit 핸들러 대신 양식을 제출하기위한 onClick 핸들러 사용과 동일합니다. 양식을 제출해야합니다.
Alex Fedoseev

4
나는 keyup지난 30 분 동안 내 문제를 해결하려고 노력하고 있었는데, 당신은 그렇게하셨습니다. 따라서 사람들 keyup양식 제출을 잡는 데 사용하지 마십시오
Nico

52

Google 이벤트 처리를 사용하는 것이 적절한 해결책처럼 보이지만 저에게는 작동하지 않습니다. 이 jQuery 솔루션은 저에게 효과적입니다.

$('#inputId').keydown(function (e) {
  if (e.which == 13 && $('.pac-container:visible').length) return false;
});

.pac-container자동 완성 일치를 보유하는 div입니다. 아이디어는 일치 항목이 표시되면 Enter 키가 활성 일치 항목을 선택한다는 것입니다. 그러나 일치 항목이 숨겨지면 (즉, 장소가 선택됨) 양식이 제출됩니다.


아름답게 작동하므로 감사합니다. 간단하고 효과적입니다.
luke_mclachlan 2015

아마도 가장 우아한 솔루션 일 것입니다. 감사합니다!
니콜라이 Traykov

그러나 빈 필드에 양식을 제출하는 입력을 허용하지 않습니까? 주소를 선택하기 전에?
amosmos

1
Chrome에서는 작동하지 않습니다. 입력이 양식 내부에 있으면 Chrome 키 이벤트가 Enter를 감지하지 못하는 것 같습니다.
Bruno

1
이 솔루션의 유일한 단점은 Google이 HTML을 변경하기로 결정하면 페이지에 삽입 .pac-container하고 다른 이름 으로 이름 을 바꾸면 중단된다는 것입니다.
저스틴 태너

21

@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)가 표시 될 때 양식이 제출되지 않도록합니다. 이제 사용자가 Enter 키를 누를 때 자동 완성 드롭 다운의 옵션이 선택되고 양식을 제출하려면 다시 눌러야합니다.

이 해결 방법을 사용하는 주된 이유는 Enter 키를 통해 옵션을 선택하자마자 양식이 전송되면 위도 및 경도 값이 숨겨진 양식 요소로 충분히 빠르게 전달되지 않는다는 것을 발견했기 때문입니다.

원래 답변에 대한 모든 크레딧.


7

이것은 나를 위해 일했습니다.

google.maps.event.addDomListener(input, 'keydown', e => {

  // If it's Enter
  if (e.keyCode === 13) {

    // Select all Google's 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에서 모든 브라우저 호환 코드로 쉽게 변환 할 수 있습니다.


나는 당신의 대답을 좋아하지만 그것을 작동시키기 위해 약간 조정해야했습니다. 내 솔루션을 게시했습니다.
schulwitz

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>

플래그는 위치가 변경되고 사용자가 입력을 누르면 이벤트가 차단되도록합니다. 결국 플래그는 falseGoogle지도의 place_changed이벤트 에 의해 설정되며 Enter 키를 눌렀을 때 양식을 제출할 수 있습니다.


이 코드는 실제로 저에게 효과적이었습니다. 노력해 주셔서 감사합니다!
Aimal Khan 2016-12-05

이 코드는 사용자가 작성하고 Enter 키를 누른 다음 아래쪽 화살표 (또는 자동 완성을 트리거하지 않는 키)를 입력하는 경우 제출을 방지합니다. 이 후 반환이 차단됩니다.
Natxet

1

다음은 저에게 잘 작동하는 간단한 코드입니다 (jquery를 사용하지 않음).

const googleAutcompleteField = this.renderer.selectRootElement(this.elem.nativeElement);
this.selectOnEnter(googleAutcompleteField);

위 코드를 따르는이 코드는 Google지도 자동 완성을 구현하는 데 사용됩니다 (이 질문에서 찾은 Enter 키 기능 유무에 관계없이).

this.autocomplete = new google.maps.places.Autocomplete(googleAutcompleteField, this.googleMapsOptions);
this.autocomplete.setFields(['address_component', 'formatted_address', 'geometry']);
this.autocomplete.addListener('place_changed', () => {
  this.zone.run(() => {
    this.googleMapsData.emit([this.autocomplete.getPlace()]);
  })
})

selectOnEnter (위의 첫 번째 코드에서 호출 됨)는 다음과 같이 정의됩니다.

selectOnEnter(inputField) {
  inputField.addEventListener("keydown", (event) => {
    const selectedItem = document.getElementsByClassName('pac-item-selected');
    if (event.key == "Enter" && selectedItem.length != 0) {
      event.preventDefault();
    }
  })
}

이 코드는 Google지도 자동 완성 필드가 사용자가 아래쪽 화살표 키를 눌러 선택하는 항목을 선택하도록합니다. 사용자가 Enter 키를 눌러 옵션을 선택하면 아무 일도 일어나지 않습니다. onSubmit () 또는 다른 명령을 트리거하려면 사용자가 Enter 키를 다시 눌러야합니다.


0

Alex의 코드는 브라우저에서 깨 졌기 때문에 수정했습니다. 이것은 나에게 완벽하게 작동합니다.

google.maps.event.addDomListener(
    document.getElementById('YOUR_ELEMENT_ID'),
    'keydown',
    function(e) {
          // If it's Enter
          if (e.keyCode === 13) {
            // Select all Google's 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's 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]);
    }
}

0

위의 짧은 답변을 시도했지만 저에게 효과가 없었고 긴 답변은 시도하고 싶지 않았으므로 다음 코드를 만들었습니다. 데모보기

이것이 귀하의 양식이라고 가정하십시오.

<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>

그러면 다음 자바 스크립트 코드가 문제를 해결합니다.

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_KEYGoogle 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>

0
$("#myinput").on("keydown", function(e) {
if (e.which == 13) {

if($(".pac-item").length>0)
        {
            $(".pac-item-selected").trigger("click");
}

}

$('.pac-item:first').trigger('click');첫 번째 결과를 선택하려는 경우 사용


0

바닐라로 할 수 있습니다.

element.addEventListener('keydown', function(e) {
    const gPlaceChoices = document.querySelector('.pac-container')
    // No choices element ? 
    if (null === gPlaceChoices) {
        return
    }
    // Get choices visivility
    let visibility = window.getComputedStyle(gPlaceChoices).display
    // In this case, enter key will do nothing
    if ('none' !== visibility && e.keyCode === 13) {
        e.preventDefault();
     }
 })
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.