我正在使用JavaScript 的Google地点自动完成API v3。它运行良好,但我想知道是否有一种方法可以强制从自动完成中进行选择,也就是说,输入将不接受任何自由格式的文本。我查看了文档,没有看到这样的选项,但觉得还是问一下比较保险。我相信我可以通过一些JavaScript来解决这个问题,但如果已经有可用的构建方法,我更愿意使用它。谢谢!
我正在使用JavaScript 的Google地点自动完成API v3。它运行良好,但我想知道是否有一种方法可以强制从自动完成中进行选择,也就是说,输入将不接受任何自由格式的文本。我查看了文档,没有看到这样的选项,但觉得还是问一下比较保险。我相信我可以通过一些JavaScript来解决这个问题,但如果已经有可用的构建方法,我更愿意使用它。谢谢!
实际上,我们所做的是以下内容:
- 每次从自动完成列表中选择一个位置时,我们会使用来自JSON响应的某些字段填充一些隐藏字段(城市名称、国家名称、经度和纬度)
- 当表单提交时,我们检查这些字段是否有值,如果没有,说明用户没有从列表中选择位置,而是自己输入了一个值。
这种方法不是以JS方式解决问题,但仍然可以很好地解决问题!
<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>
谷歌地点API目前不支持此功能。如果您认为这将是一个有用的功能,请提交地点API-功能请求。
blur()
事件来强制选择最后一个选定的地址。blur
和place_changed
事件之间的冲突。<input type="text" placeholder="Your address" id="autocomplete">
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);
});
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 = "";
});
当输入改变时退出值对我很有用。它强制使用Google Places。
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";
}
});
}
您可以使用输入模式标签,强制用户根据Google Autocomplete API选择一个预定的选项。
输入:
<form>
<input type="text" onkeyup="changePatterns()" onchange="changePatterns()" id="autocomplete" required pattern="">
<input type="submit">
</form>
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);
});
}
因为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;
<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>
查看https://dev59.com/q1wY5IYBdhLWcg3w0Kcs#52534805
更简单的方法可能是:
let placeInputEl = document.getElementById("placeInput");
let autcomplete = new google.maps.places.Autocomplete(placeInputEl);
placeInputEl.addEventListener("change", () => {
//this fires when the user changes to a non-selection / freeform text
doStuff(true);
});
autocomplete.addListener("place_changed", () => {
//this fires when the user selects a place from Google
doStuff(false);
});
function doStuff(isFreeText) {
//maybe clear the selection or do whatever you need to reset
if (isFreeText) {
placeInputEl.value = "";
return;
}
// handle a place selection
}
<input id="placeInput" />
这让您可以清除输入、确定验证、重置输入或者任何您想要做的事情,以使选择变为必选项。
place_changed
事件仅在用户选择输入或按下回车键时触发。
change
事件在 place_changed
之前触发,因此您可能能够应用自己的逻辑而不会干扰谷歌的 API 调用。
就像他们所提到的那样,Google Autocomplete API不支持此功能。 我找到了一种方法来使其工作,即创建一个隐藏元素来存储所选地点,然后检查它是否等于自动完成输入。
/*----------------------------------------------------*/
/* check if it's valid address
/*----------------------------------------------------*/
function checkAddress(location, validLocation) {
if (location.val() == validLocation.val()) {
return true;
}
return false;
}
/*----------------------------------------------------*/
/* initialize auto complete address
/*----------------------------------------------------*/
function initialize() {
let input = document.getElementById('autocomplete-input');
let inputHidden = document.getElementById('autocomplete-input-hidden');
let options = {
types: ['(regions)'],
componentRestrictions: {country: "tn"}
};
let autocomplete =new google.maps.places.Autocomplete(input, options);
autocomplete.setFields(['formatted_address']);
autocomplete.addListener('place_changed', function () {
inputHidden.value= autocomplete.getPlace().formatted_address;
});
}
在你的主函数中调用该函数。
let location = $('#autocomplete-input');
let validLocation = $('#autocomplete-input-hidden');
checkAddress(location,validLocation);
在你的HTML中:
<input id="autocomplete-input" type="text">
<input id="autocomplete-input-hidden" type="hidden" >