使用 google api 自动完成地址

Autocomplete address with google api

提问人:Joe 提问时间:3/3/2023 最后编辑:MrUpsidownJoe 更新时间:3/4/2023 访问量:637

问:

我编写了一个简单的页面,用户可以在其中将他们的地址输入到搜索区域。根据输入,地址会通过 Google Maps API 自动完成。用户选择其中一个地址后,将填写字段。一切正常,省/州除外。下拉列表根据国家/地区下拉列表填充正确的省/州。但是,它无法根据自动完成选择选择正确的省/州。我在这里做错了什么?

<!DOCTYPE html>
<html>

<head>
    <title>Google Places API Autocomplete</title>
    <script
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places"></script>
    <script>
        function initialize() {
            var senderStreetInput = document.getElementById('sender_street');
            var senderApartmentInput = document.getElementById('sender_apartment');
            var senderCityInput = document.getElementById('sender_city');
            var senderStateSelect = document.getElementById('sender_state');
            var senderPostalCodeInput = document.getElementById('sender_postal_code');
            var senderCountrySelect = document.getElementById('sender_country');
            var senderStreetAutocomplete = new google.maps.places.Autocomplete(senderStreetInput, {
                types: ['address']
            });
            var senderApartmentAutocomplete = new google.maps.places.Autocomplete(senderApartmentInput, {
                types: ['address']
            });
            var senderCityAutocomplete = new google.maps.places.Autocomplete(senderCityInput, {
                types: ['(cities)']
            });
            senderCountrySelect.addEventListener('change', function () {
                var country = this.value;
                senderStateSelect.innerHTML = '';
                if (country === 'Canada') {
                    var provinces = [
                        'Alberta', 'British Columbia', 'Manitoba', 'New Brunswick', 'Newfoundland and Labrador',
                        'Northwest Territories', 'Nova Scotia', 'Nunavut', 'Ontario', 'Prince Edward Island',
                        'Quebec', 'Saskatchewan', 'Yukon'
                    ];
                } else if (country === 'United States') {
                    var states = [
                        'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut',
                        'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa',
                        'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan',
                        'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
                        'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio',
                        'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota',
                        'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia',
                        'Wisconsin', 'Wyoming'
                    ];
                }
                var option = document.createElement('option');
                option.value = '';
                option.textContent = 'Select a state/province';
                senderStateSelect.appendChild(option);
                if (provinces) {
                    provinces.forEach(function (province) {
                        var option = document.createElement('option');
                        option.value = province;
                        option.textContent = province;
                        senderStateSelect.appendChild(option);
                    });
                } else if (states) {
                    states.forEach(function (state) {
                        var option = document.createElement('option');
                        option.value = state;
                        option.textContent = state;
                        senderStateSelect.appendChild(option);
                    });
                }
                senderStateSelect.disabled = false;
            });
            senderStreetAutocomplete.addListener('place_changed', function () {
                var place = senderStreetAutocomplete.getPlace();
                if (!place.geometry) {
                    return;
                }
                senderApartmentInput.value = '';
                senderCityInput.value = '';
                senderStateSelect.value = '';
                senderPostalCodeInput.value = '';
                senderCountrySelect.value = '';
                for (var i = 0; i < place.address_components.length; i++) {
                    var component = place.address_components[i];
                    if (component.types.indexOf('street_number') !== -1) {
                        senderStreetInput.value = component.long_name;
                    } else if (component.types.indexOf('route') !== -1) {
                        senderStreetInput.value += ' ' + component.long_name;
                    } else if (component.types.indexOf('locality') !== -1) {
                        senderCityInput.value = component.long_name;
                    } else if (component.types.indexOf('administrative_area_level_1') !== -1) {
                        senderStateSelect.value = component.long_name;
                    } else if (component.types.indexOf('postal_code') !== -1) {
                        senderPostalCodeInput.value = component.long_name;
                    } else if (component.types.indexOf('country') !== -1) {
                        senderCountrySelect.value = component.long_name;
                        senderCountrySelect.dispatchEvent(new Event('change'));
                    }
                }
            });

            senderCityAutocomplete.addListener('place_changed', function () {
                var place = senderCityAutocomplete.getPlace();
                if (!place.geometry) {
                    return;
                }
                senderStreetInput.value = '';
                senderApartmentInput.value = '';
                senderStateSelect.value = '';
                senderPostalCodeInput.value = '';
                senderCountrySelect.value = '';
                for (var i = 0; i < place.address_components.length; i++) {
                    var component = place.address_components[i];
                    if (component.types.indexOf('locality') !== -1) {
                        senderCityInput.value = component.long_name;
                    } else if (component.types.indexOf('administrative_area_level_1') !== -1) {
                        senderStateSelect.value = component.long_name;
                    } else if (component.types.indexOf('country') !== -1) {
                        senderCountrySelect.value = component.long_name;
                        senderCountrySelect.dispatchEvent(new Event('change'));
                    }
                }
            });
        }
        google.maps.event.addDomListener(window, 'load', initialize);
    </script>

</head>

<body>
    <div>
        <label for="sender_street">Street Address:</label>
        <input type="text" id="sender_street" name="sender_street">
    </div>
    <div>
        <label for="sender_apartment">Apartment, suite, etc.:</label>
        <input type="text" id="sender_apartment" name="sender_apartment">
    </div>
    <div>
        <label for="sender_city">City:</label>
        <input type="text" id="sender_city" name="sender_city" required>
    </div>
    <div>
        <label for="sender_state">State/Province:</label>
        <select id="sender_state" name="sender_state" disabled required>
        </select>
    </div>
    <div>
        <label for="sender_postal_code">Zip/Postal Code:</label>
        <input type="text" id="sender_postal_code" name="sender_postal_code" required>
        <small>Enter 3-10 alphanumeric characters (letters A-Z, numbers 0-9) only.</small>
    </div>
    <div>
        <label for="sender_country">Select Country:</label>
        <select id="sender_country" name="sender_country">
            <option value="">Select a country</option>
            <option value="United States">United States</option>
            <option value="Canada">Canada</option>
        </select>
    </div>
</body>

</html>

JavaScript HTML 谷歌地图 街道地址

评论

1赞 geocodezip 3/3/2023
为什么同一个地址有 3 个自动完成?
0赞 Joe 3/3/2023
@geocodezip,它允许用户搜索没有或州的城市。如果他们出于某种原因选择更改它。它会自动完成,以使他们更容易。
0赞 geocodezip 3/3/2023
但它们相互干扰......

答:

1赞 MrUpsidown 3/3/2023 #1

脚本流中存在问题,可能与 3 个自动完成字段以及“重置”或清空状态选择值有关。

我将您的脚本精简为只有加拿大省份的最小版本,效果很好。我已经在蒙特利尔、温尼伯和温哥华的几个地址尝试过。

注意:您还应该加载带有参数的 API,并将其设置为英语。否则,“自动完成”将以不同的语言加载,具体取决于使用者。州、省、国家/地区名称甚至城市名称(在某些情况下)可能会以用户语言返回,因此您的列表将不匹配。language

我所做的一个小改动是,魁北克应该拼写为魁北克,因为这是 API 返回的方式。

function initialize() {

  var senderStreetInput = document.getElementById('sender_street');
  var senderStateSelect = document.getElementById('sender_state');

  var provinces = [
    'Alberta', 'British Columbia', 'Manitoba', 'New Brunswick', 'Newfoundland and Labrador',
    'Northwest Territories', 'Nova Scotia', 'Nunavut', 'Ontario', 'Prince Edward Island',
    'Québec', 'Saskatchewan', 'Yukon'
  ];

  provinces.forEach(function(province) {
    var option = document.createElement('option');
    option.value = province;
    option.textContent = province;
    senderStateSelect.appendChild(option);
  });

  var senderStreetAutocomplete = new google.maps.places.Autocomplete(senderStreetInput, {
    types: ['address']
  });

  senderStreetAutocomplete.addListener('place_changed', function() {
    var place = senderStreetAutocomplete.getPlace();
    if (!place.geometry) {
      return;
    }

    for (var i = 0; i < place.address_components.length; i++) {
      var component = place.address_components[i];
      if (component.types.indexOf('administrative_area_level_1') !== -1) {
        senderStateSelect.value = component.long_name;
      }
    }
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
<div>
  <label for="sender_street">Street Address:</label>
  <input type="text" id="sender_street" name="sender_street">
</div>
<div>
  <label for="sender_state">State/Province:</label>
  <select id="sender_state" name="sender_state">
  </select>
</div>

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&language=en"></script>