2012-07-09 45 views
62

私はGoogleオートコンプリートがHTMLフォームのテキストフィールド用に設定されており、完全に機能しています。Googleオートコンプリート - 選択入力して選択

しかし、提案のリストが表示され、矢印を使用してスクロールしてEnterを使用して選択すると、フォームが送信されますが、まだ入力するボックスがあります。 を入力すると、が入力されます。

これをどのように制御できますか?フォームの送信からの入力を停止し、代わりにオートコンプリートからの提案を選択することはできますか?

ありがとうございます! {S}

答えて

89

あなたが入力したがヒットした際に提出されたフォームを停止するpreventDefaultを使用することができ、私はこのようなものを使用:取扱Googleのイベントの使用

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

これはフィールドからの送信を常にキャンセルします。ユーザがオートコンプリートオプションを選択するためにイントロを押した場合、送信をキャンセルする必要があります。 –

+1

宝石のように機能します。入力してリストからオートコンプリートオプションを選択しても、フォームを送信しなくなりました。 –

+0

これは解決策よりも、よりアンティパターンです。 onSubmitハンドラの代わりにフォームを送信するonClickハンドラの使用法と同じです。入力はフォームを提出する必要があります。 –

46

を適切な解決策のように思えるが、それは働いていません私のために。このjQueryのソリューションは私のために働いている:

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

.pac-containerは、オートコンプリートの一致を保持しているdiv要素です。アイデアは、マッチが見えるときにEnterキーがアクティブなマッチを選ぶということです。しかし、マッチが隠されている場合(つまり、場所が選択された場合)、フォームが送信されます。

+0

はきれいに動作しますので、ありがとうございます。シンプルで効果的です。 –

+0

おそらく最も洗練されたソリューションです。ありがとうございました! –

+0

しかし、それは空のフィールドにフォームを提出する入力を許可しないでしょうか?アドレスを選ぶ前に? – amosmos

3

私が@ 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>

フラグは場所が&ユーザーのヒットを入力して変更されている場合、イベントがブロックされていることを保証

をやってしまったものです。最終的には、Googleマップの place_changedイベントによってフラグが falseに設定されます。これにより、入力キーを押すとフォームが送信されます。

+0

このコードは実際に私のために働いた、努力をいただきありがとうございます! –

13

私はこれを生産する@srenと@mmaloneから最初の2つの答え合併しました:ページ上で完璧に動作

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キーを使用して、緯度と経度の値が隠れたフォーム要素。

元の回答に対するすべてのクレジット

+1

シンプルで完璧に動作します。 –

3

この1つは私の仕事:

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から任意のブラウザと互換性のあるコードに変換することができます。

+0

私はあなたの答えが好きですが、それを動作させるにはちょっと微調整しなければなりませんでした。私のソリューションを掲載しました。 – schulwitz

0

私はブラウザで壊れたので、私はアレックスのコードを微調整しました。これは私のために完璧に動作します:

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

私は上記の短い答えを試みたが、彼らは私のために動作しませんでした、と長い答えは、私はそれらを試してみたくなかったので、私は次のように作成しました私にとってはかなりうまくいったコードです。 See Demo

これはあなたのフォームであると仮定します

<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> 
関連する問題