javascript Google Places 自动完成强制选择
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14652507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google Places Autocomplete Force Selection
提问by TheMethod
I am using the JavaScript Google places autocomplete API v3. It works fine but I was wondering if there was a way to force the selection from the autocomplete, that is input that will not accept any free form text. I looked at the docs and didn't see such an option but figured I would ask just to be safe. I'm sure I could work out a way to do it with some JavaScript but would prefer to use an already built method if it is available. Thanks!
我正在使用 JavaScript Google 地点自动完成 API v3。它工作正常,但我想知道是否有办法强制从自动完成中进行选择,即不接受任何自由格式文本的输入。我查看了文档并没有看到这样的选项,但我想我会要求只是为了安全。我确信我可以用一些 JavaScript 找到一种方法来做到这一点,但如果可以的话,我更愿意使用已经构建的方法。谢谢!
采纳答案by Chris Green
The Google Places API does not currently support this feature. If you believe this would be a useful feature please submit a Places API - Feature Request.
Google Places API 目前不支持此功能。如果您认为这将是一个有用的功能,请提交Places API - 功能请求。
回答by Iraklis Alexopoulos
Actually, what we did was the following:
- Every time a location is picked from the Auto complete list, we populate some hidden fields with some fields coming from the JSON response (city name, country name, longitude and latitude)
- When the form is submitted, we check if these fields have values, if they don't, it means that the user instead of selecting a location from the list, he just entered a value himself.
实际上,我们所做的如下:
- 每次从自动完成列表中选择一个位置时,我们都会使用来自 JSON 响应的一些字段(城市名称、国家名称、经度和纬度)填充一些隐藏字段
- 当表单提交后,我们检查这些字段是否有值,如果没有,则表示用户不是从列表中选择位置,而是自己输入了一个值。
It is not solving the problem in a JS way, but still, it does the trick just fine!
它不是以 JS 的方式解决问题,但它仍然可以很好地解决问题!
回答by Digvijaysinh Zala
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"
type="text/javascript"></script>
<script>
var IsplaceChange = false;
$(document).ready(function () {
var input = document.getElementById('txtlocation');
var autocomplete = new google.maps.places.Autocomplete(input, { types: ['(cities)'] });
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
IsplaceChange = true;
});
$("#txtlocation").keydown(function () {
IsplaceChange = false;
});
$("#btnsubmit").click(function () {
if (IsplaceChange == false) {
$("#txtlocation").val('');
alert("please Enter valid location");
}
else {
alert($("#txtlocation").val());
}
});
});
</script>
回答by Charlesthk
The following solution did the trick for me (with jQuery). The idea is to use the blur()
event to force the last selected address once the input loses focus.
以下解决方案对我有用(使用 jQuery)。这个想法是blur()
在输入失去焦点时使用该事件强制最后选择的地址。
We add a timeout to prevent a conflict between the blur
and the place_changed
events.
我们添加超时以防止blur
和place_changed
事件之间发生冲突。
Consider the following html:
考虑以下 html:
<input type="text" placeholder="Your address" id="autocomplete">
And the following javascript :
以及以下 javascript :
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{types: ['geocode']});
autocomplete.addListener('place_changed', fillInAddress);
var currentAddress = {
line_1: "",
line_2: "",
zipcode: "",
city: "",
country: "",
lat: "",
lng: "",
one_liner: ""
};
function fillInAddress() {
var place = this.autocomplete.getPlace();
// reset the address
currentAddress = {
line_1: "",
line_2: "",
zipcode: "",
city: "",
country: "",
lat: "",
lng: "",
one_liner: place.formatted_address
};
// store relevant info in currentAddress
var results = place.address_components.reduce(function(prev, current) {
prev[current.types[0]] = current['long_name'];
return prev;
}, {})
if (results.hasOwnProperty('route')) {
currentAddress.line_1 = results.route;
}
if (results.hasOwnProperty('street_number')) {
currentAddress.line_1 = results.street_number + " " + currentAddress.line_1;
}
if (results.hasOwnProperty('postal_code')) {
currentAddress.zipcode = results.postal_code;
}
if (results.hasOwnProperty('locality')) {
currentAddress.city = results.locality;
}
if (results.hasOwnProperty('country')) {
currentAddress.country = results.country;
}
currentAddress.lat = Number(place.geometry.location.lat()).toFixed(6);
currentAddress.lng = Number(place.geometry.location.lng()).toFixed(6);
}
$('#autocomplete').blur(function() {
var address = $('#autocomplete').val();
// we set a timeout to prevent conflicts between blur and place_changed events
var timeout = setTimeout(function() {
// release timeout
clearTimeout(timeout);
if (address !== currentAddress.one_liner) {
$('#autocomplete').val(currentAddress.one_liner);
}
}, 500);
});
I hope this helps.
我希望这有帮助。
回答by Martí Cols
var options = {
language: 'en',
types: ['(cities)'],
};
var input = document.getElementById('city');
var autocomplete = new google.maps.places.Autocomplete(input, options);
input.addEventListener("change", function(){
input.value = "";
});
Quiting the value when the input changes works for me. It forces to use Google Places.
当输入更改时退出值对我有用。它强制使用 Google 地方信息。
回答by user2027454
I was having the same problem, below is a function that I came up with as a work-around. This could be used in combination with an event such as onchange or onkeyup. Hope it helps!
我遇到了同样的问题,下面是我想出的一个解决方法。这可以与诸如 onchange 或 onkeyup 之类的事件结合使用。希望能帮助到你!
//Arguments:
//Arguments:
address - string containing the place that you want to validate
address_success_div - div object specifically used for displaying validation
address - string containing the place that you want to validate
address_success_div - div object specifically used for displaying validation
function is_location_valid(address, address_success_div)
{
var geocoder = new google.maps.Geocoder();
geocoder.geocode( {"address": address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
address_success_div.innerHTML = "SUCCESS";
}
else
{
address_success_div.innerHTML = "FAILURE";
}
});
}
回答by Gabriel Monteiro
You can use the input pattern tag, forcing the user to choose a predeterminate based on Google Autocomplete API.
您可以使用输入模式标签,强制用户选择基于 Google Autocomplete API 的预设。
The input:
输入:
<form>
<input type="text" onkeyup="changePatterns()" onchange="changePatterns()" id="autocomplete" required pattern="">
<input type="submit">
</form>
The JS file:
JS文件:
function changePatterns() {
let input = document.getElementById('autocomplete').value;
let regExp = new RegExp(' ', 'g');
input = input.replace(regExp, '%20');
let mapsURL = 'https://maps.googleapis.com/maps/api/place/autocomplete/json'
mapsURL += '?types=geocode';
mapsURL += '&key=YOUR-KEY-HERE';
mapsURL += `&input=${input}`;
const endpoint = 'middle.php';
let formData = new FormData();
formData.append('url', mapsURL);
fetch(endpoint, {
method: 'post',
body: formData
})
.then(blob => blob.json())
.then(response => {
const predictions = response.predictions;
let {length} = predictions;
let pattern = '';
for(let i = 0; i < length; i++){
pattern += i == 0 ? '' : '|';
pattern += predictions[i].description
}
const input = document.getElementById('autocomplete');
input.setAttribute('pattern', pattern);
});
}
I had to use a php intermediate because of problems with CORS policy:
由于 CORS 策略的问题,我不得不使用 php 中间体:
<?php
header('Content-Type: application/json');
$url = $_POST['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //remove on upload
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "https://www.notmydomain.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);
echo $result;
回答by Amit Shah
I solved my issue using this code found here
我使用此代码找到解决我的问题在这里
<asp:TextBox runat="server" ID="TextBox1" />
<input type="button" id="btnSubmit" name="name" value="Validate" />
<div id="dvMap">
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyBE1J5Pe_GZXBR_x9TXOv6TU5vtCSmEPW4"></script>
<script type="text/javascript">
var isPlaceChanged = false;
google.maps.event.addDomListener(window, 'load', function () {
var places = new google.maps.places.Autocomplete(document.getElementById('<%= TextBox1.ClientID %>'));
google.maps.event.addListener(places, 'place_changed', function () {
isPlaceChanged = true;
var geocoder = new google.maps.Geocoder();
var place = places.getPlace();
var address = place.formatted_address;
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var mapOptions = { center: new google.maps.LatLng(latitude, longitude), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var marker = new google.maps.Marker({ position: new google.maps.LatLng(latitude, longitude), map: map });
} else {
alert("Request failed.")
}
});
});
});
$(function () {
$("#TextBox1").keydown(function () {
isPlaceChanged = false;
});
$("#btnSubmit").click(function () {
if (!isPlaceChanged) {
$("#TextBox1").val('');
alert("Please Enter valid location");
}
else {
alert($("#TextBox1").val());
}
});
});
</script>
回答by user3554084
I modified a bit of code from google places example.
我修改了 google 地方示例中的一些代码。
<input type="text" id="address" onchange="check();" required>
<input type="text" id="address" onchange="check();" required>
function check() {
console.log("check");
try {
var place = autocomplete.getPlace();
console.log(place);
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
window.alert("Please enter address suggested by google");
return;
}
} catch (err) {
window.alert("Please enter address suggested by google");
}
}
回答by Assaf Katz
Hia I have managed to do that by creating the autocomplete object each time the user focuses the input field, and checking it's value each time it's blured:
嗨,我设法通过在每次用户聚焦输入字段时创建自动完成对象并在每次模糊时检查它的值来做到这一点:
var autocompleteField;
var input = document.getElementById('YOUR_INPUT');
$('#YOUR_INPUT').focus(function(e){
if(autocompleteField){
autocompleteField=null;
}
autocompleteField = new google.maps.places.Autocomplete(input);
});
$('#YOUR_INPUT').blur(function(e){
var results = autocompleteField.getPlace();
if(!results){
$(this).attr('value','');
}
});