2012-05-04 63 views
4

我使用谷歌地點自動完成地點的建議。現在這就是我想要的:當用戶鍵入的位置不在谷歌數據庫中時,即谷歌返回零結果,我需要能夠捕獲零結果事件並激發我的客戶自動填充。谷歌地點自動完成返回零結果時發現

如何查找谷歌何時返回零結果?如果結果爲零,autocomplete.getPlace()將返回一個狀態,但這是在place_changed事件內部,僅當用戶從下拉列表中選擇一個建議時才觸發。如何讓它在place_changed事件之外工作?

這是我使用的代碼,請大家在此基礎上建議:

autocomplete = new google.maps.places.Autocomplete(input,options); 
google.maps.event.addListener(autocomplete, 'place_changed', function() { 
    var place = autocomplete.getPlace(); 
    document.getElementById('place_name').value = place.name; 
    document.getElementById('location_lat').value = place.geometry.location.lat(); 
    document.getElementById('location_lon').value = place.geometry.location.lng(); 
    document.getElementById('location_add').value = place.formatted_address; 
    $('#locationInput').attr('title', place.formatted_address); 
}); 

回答

6

實測值特技,

AutoComplete觸發由keyup事件輸入節點,則:由display: none;如果

隱藏結果下拉列表沒有結果

顯示結果dropdown列表中明確display風格,如果有導致

您可以通過document.getElementsByClassName('pac-container')[0](本地)或$('.pac-container')(jQuery的)得到下拉列表

所以只設置下拉列表「塊」的display然後跟蹤其檢測結果狀態。

google official sample改性的簡單示例:

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Google Maps JavaScript API v3 Example: Places Autocomplete</title> 
     <script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places" 
      type="text/javascript"></script> 

     <style type="text/css"> 
      body { 
       font-family: sans-serif; 
       font-size: 14px; 
      } 
      #map_canvas { 
       height: 400px; 
       width: 600px; 
       margin-top: 0.6em; 
      } 
     </style> 

     <script type="text/javascript"> 
      var ns = {}; // a name space 
      ns.checktimes = 0; // a couter of check times 
      // the check function 
      // @param dropdown: the drop-down list of Places.AutoComplete 
      // @param msg: the div to show message 
      ns._doCheck = function (dropdown, msg) { 
       if (dropdown.style.display == '') { 
        msg.innerHTML = 'has results? true'; 
        ns.checkTimer = null; 
       } 
       else if (dropdown.style.display == 'none') { 
        msg.innerHTML = 'has results? false'; 
        ns.checkTimer = null; 
       } else if (ns.checktimes < 20) { // check at most 10 seconds 
        ns.checktimes++; 
        ns.checkTimer = setTimeout(function() { 
         ns._doCheck(dropdown, msg); 
        }, 500); 
       } 
      } 
      function initialize() { 
       var mapOptions = { 
        center: new google.maps.LatLng(-33.8688, 151.2195), 
        zoom: 13, 
        mapTypeId: google.maps.MapTypeId.ROADMAP 
       }; 
      var map = new google.maps.Map(document.getElementById('map_canvas'), 
       mapOptions); 

      var input = document.getElementById('searchTextField'); 
      var autocomplete = new google.maps.places.Autocomplete(input); 

      autocomplete.bindTo('bounds', map); 

      var infowindow = new google.maps.InfoWindow(); 
      var marker = new google.maps.Marker({ 
       map: map 
      }); 

      google.maps.event.addListener(autocomplete, 'place_changed', function() { 
       infowindow.close(); 
       var place = autocomplete.getPlace(); 
      if (place.geometry.viewport) { 
       map.fitBounds(place.geometry.viewport); 
      } else { 
       map.setCenter(place.geometry.location); 
       map.setZoom(17); // Why 17? Because it looks good. 
      } 

      var image = new google.maps.MarkerImage(
       place.icon, 
       new google.maps.Size(71, 71), 
       new google.maps.Point(0, 0), 
       new google.maps.Point(17, 34), 
       new google.maps.Size(35, 35)); 
      marker.setIcon(image); 
      marker.setPosition(place.geometry.location); 

      var address = ''; 
      if (place.address_components) { 
       address = [(place.address_components[0] && 
       place.address_components[0].short_name || ''), 
       (place.address_components[1] && 
       place.address_components[1].short_name || ''), 
       (place.address_components[2] && 
       place.address_components[2].short_name || '') 
       ].join(' '); 
      } 

      infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); 
      infowindow.open(map, marker); 
      // update stored value 
      ns.oldValue = document.getElementById('searchTextField').value; 
     }); 

     // Sets a listener on a radio button to change the filter type on Places 
     // Autocomplete. 
     function setupClickListener(id, types) { 
      var radioButton = document.getElementById(id); 
      google.maps.event.addDomListener(radioButton, 'click', function() { 
      autocomplete.setTypes(types); 
      }); 
     } 

     setupClickListener('changetype-all', []); 
     setupClickListener('changetype-establishment', ['establishment']); 
     setupClickListener('changetype-geocode', ['geocode']); 
     } 

     // to check whether responsee and has results 
     function startCheck() { 
      // the input node 
      var inp = document.getElementById('searchTextField'), 
       value = inp.value; // value of input node 
      if (value && ns.oldValue != value) { // has value and changed, start check 
       // drop-down list and message div 
       var dropdown = document.getElementsByClassName('pac-container')[0], 
        msg = document.getElementById('msg'); 
       // trick! change style to display='block' 
       dropdown.style.display = 'block'; 
       // update stored value 
       ns.oldValue = value; 
       // initiate checktimes 
       ns.checktimes = 0; 
       // clear previous timer if exists 
       if (ns.checkTimer) 
        clearTimeout (ns.checkTimer); 
       ns.checkTimer = setTimeout(function() { 
        ns._doCheck(dropdown, msg); 
       }, 500); 
      } 
     } 
     google.maps.event.addDomListener(window, 'load', initialize); 
    </script> 
    </head> 
    <body> 
     <div> 
      <div id="msg">has results? </div> 
      <input id="searchTextField" type="text" size="50" onkeyup="startCheck();"> 
      <input type="radio" name="type" id="changetype-all" checked="checked"> 
      <label for="changetype-all">All</label> 

      <input type="radio" name="type" id="changetype-establishment"> 
      <label for="changetype-establishment">Establishments</label> 

      <input type="radio" name="type" id="changetype-geocode"> 
      <label for="changetype-geocode">Geocodes</lable> 
     </div> 
     <div id="map_canvas"></div> 
    </body> 
</html> 
+0

不錯的解決方案Benbai – Ninja

+0

真棒,謝謝! –

2

我覺得您的情況可能會比谷歌返回零個結果不同。在您的問題中的一個假設是place_changed事件「僅在[用戶]從下拉列表中選擇建議時觸發」是不正確的。從google.maps.places.Autocomplete事件文檔爲place_changed

時可供用戶選擇一個地方 一組PlaceResult此事件被觸發。 如果用戶輸入控件未建議 的地方的名稱並按下Enter鍵,則將觸發 place_changed事件,該事件包含名稱屬性 中的用戶輸入,但未定義其他屬性。

否則,Google應該返回結果,因爲用戶選擇了自動填充的下拉選項中的一個結果。如果用戶直接進入不是什麼推動你的情況下,不應該爲結果爲零檢查只是涉及檢查一個,一些或google.maps.places.PlaceResult屬性,如的一個子集:

  • 的:的google.maps.GeocoderAddressComponentaddress_components陣列小號
  • id
  • name
  • reference
  • types陣列串(例如[politicallocality]或[restaurantestablishment])
+0

1這是正確的。 –