2011-11-12 60 views
0

我在jQuery和Javascript上很薄弱。我想採用這個現有的代碼,並以郵政格式向用戶提供完整的地址......就像您將信件或fedex信封一樣。jQuery Geocode獲取郵政地址

用戶開始在地址欄中鍵入地址,jQuery自動完成啓動。當用戶看到完整的地址時,他們點擊地址,然後我希望它隨着用戶選擇傳播一個測試框,但是在郵政格式。

下面是HTML頁面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 

<head> 
<title>Get Address Details</title> 
     <script type="text/javascript" src="js/jquery-1.6.4.min.js"></script> 
     <script src="http://maps.google.com/maps/api/js?sensor=false"></script> 
     <script src="js/jquery-ui-1.8.7.min.js"></script> 
     <script src="js/jquery.ui.addresspicker.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
       $("#address1").addresspicker({ 
           elements: { 
           locality: '#city', 
           lat:  '#lat', 
           lng:  '#lng', 
           country: '#country' 
           } 
          }); 
     }); 
     </script> 

</head> 

<body> 

<form action="submit.php" method="post"> 
     <fieldset style="width: 300px; margin-bottom: 100px;"><legend>begin typing address</legend> 
     <label for="address1">Input Address: </label><input name="address1" id="address1" type="text"><br /></fieldset> 
     <fieldset style="width: 300px; text-align: right;"><legend>see results here</legend> 
     <label for="address2">Street Address: </label><input name="address2" id="address2" type="text"><br /> 

     <label for="lat">Lat: </label><input name="lat" id="lat" type="text"><br /> 

     <label for="lng">Lng: </label><input name="lng" id="lng" type="text"><br /> 

     <label for="city">City: </label><input name="city" id="city" type="text"><br /> 

     <label for="country">Country: </label><input name="country" id="country" type="text"><br /><br /> 

     <label for="postal">Postal Address: </label><textarea name="postal" id="postal" ></textarea><br /> 

     </fieldset> 

</form> 
</body> 

</html> 

的地址選擇器的JavaScript頁面的下方,其他JS網頁是當前版本

/* 
* jQuery UI addresspicker @VERSION 
* 
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) 
* Dual licensed under the MIT or GPL Version 2 licenses. 
* http://jquery.org/license 
* 
* http://docs.jquery.com/UI/Progressbar 
* 
* Depends: 
* jquery.ui.core.js 
* jquery.ui.widget.js 
* jquery.ui.autocomplete.js 
*/ 
(function($, undefined) { 

$.widget("ui.addresspicker", { 
    options: { 
     appendAddressString: "", 
     mapOptions: { 
      zoom: 5, 
      center: new google.maps.LatLng(46, 2), 
      scrollwheel: false, 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
     }, 
     elements: { 
      map: false, 
      lat: false, 
      lng: false, 
      locality: false, 
      country: false 
     }, 
     draggableMarker: true 
    }, 

    marker: function() { 
     return this.gmarker; 
    }, 

    map: function() { 
     return this.gmap; 
    }, 

    updatePosition: function() { 
    this._updatePosition(this.gmarker.getPosition()); 
    }, 

    reloadPosition: function() { 
    this.gmarker.setVisible(true); 
    this.gmarker.setPosition(new google.maps.LatLng(this.lat.val(), this.lng.val())); 
    this.gmap.setCenter(this.gmarker.getPosition()); 
    }, 

    selected: function() { 
    return this.selectedResult; 
    }, 

    _create: function() { 
     this.geocoder = new google.maps.Geocoder(); 
     this.element.autocomplete({ 
      source: $.proxy(this._geocode, this), 
      focus: $.proxy(this._focusAddress, this), 
      select: $.proxy(this._selectAddress, this) 
     }); 

     this.lat  = $(this.options.elements.lat); 
     this.lng  = $(this.options.elements.lng); 
     this.locality = $(this.options.elements.locality); 
     this.country = $(this.options.elements.country); 
     if (this.options.elements.map) { 
      this.mapElement = $(this.options.elements.map); 
     this._initMap(); 
     } 
    }, 

    _initMap: function() { 
    if (this.lat && this.lat.val()) { 
     this.options.mapOptions.center = new google.maps.LatLng(this.lat.val(), this.lng.val()); 
    } 

    this.gmap = new google.maps.Map(this.mapElement[0], this.options.mapOptions); 
    this.gmarker = new google.maps.Marker({ 
     position: this.options.mapOptions.center, 
     map:this.gmap, 
     draggable: this.options.draggableMarker}); 
    google.maps.event.addListener(this.gmarker, 'dragend', $.proxy(this._markerMoved, this)); 
    this.gmarker.setVisible(false); 
    }, 

    _updatePosition: function(location) { 
    if (this.lat) { 
     this.lat.val(location.lat()); 
    } 
    if (this.lng) { 
     this.lng.val(location.lng()); 
    } 
    }, 

    _markerMoved: function() { 
    this._updatePosition(this.gmarker.getPosition()); 
    }, 

    // Autocomplete source method: fill its suggests with google geocoder results 
    _geocode: function(request, response) { 
    var address = request.term, self = this; 
    this.geocoder.geocode({ 'address': address + this.options.appendAddressString}, function(results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
     for (var i = 0; i < results.length; i++) { 
      results[i].label = results[i].formatted_address; 
     }; 
     } 
     response(results); 
    }) 
    }, 

    _findInfo: function(result, type) { 
    for (var i = 0; i < result.address_components.length; i++) { 
     var component = result.address_components[i]; 
     if (component.types.indexOf(type) !=-1) { 
     return component.long_name; 
     } 
    } 
    return false; 
    }, 

    _focusAddress: function(event, ui) { 
    var address = ui.item; 
    if (!address) { 
     return; 
    } 

    if (this.gmarker) { 
     this.gmarker.setPosition(address.geometry.location); 
     this.gmarker.setVisible(true); 

     this.gmap.fitBounds(address.geometry.viewport); 
    } 
    this._updatePosition(address.geometry.location); 

    if (this.locality) { 
     this.locality.val(this._findInfo(address, 'locality')); 
    } 

     if (this.address) { 
     this.address.val(this._findInfo(address, 'address')); 
    } 
    if (this.country) { 
     this.country.val(this._findInfo(address, 'country')); 
    } 
    }, 

    _selectAddress: function(event, ui) { 
    this.selectedResult = ui.item; 
    } 
}); 

$.extend($.ui.addresspicker, { 
    version: "@VERSION" 
}); 


// make IE think it doesn't suck 
if(!Array.indexOf){ 
    Array.prototype.indexOf = function(obj){ 
     for(var i=0; i<this.length; i++){ 
      if(this[i]==obj){ 
       return i; 
      } 
     } 
     return -1; 
    } 
} 

})(jQuery); 

回答

1

我認爲使用該插件的可能是矯枉過正爲你的情況。它包括處理地圖等的代碼,您不需要自動完成地址。使用jQueryUI autocomplete(你已經對插件有依賴),這隻需要幾行代碼。

我會用這樣的:

$(document).ready(function() { 
    var geocoder = new google.maps.Geocoder(); 
    $("#address1").autocomplete({ 
     source: function (request, response) { 
      geocoder.geocode({ address: request.term }, function (results, status) { 
      if (status === google.maps.GeocoderStatus.OK) { 
       response($.map(results, function(result) { 
       if ($.inArray("street_address", result.types) >= 0) { 
        return result.formatted_address; 
       } 
       })); 
      } 
      }); 
     }, 
     select: function (event, ui) { 
      var parts = ui.item.label.split(",") 
       , address1 = parts[0] 
       , address2 = parts.slice(1).join(",").trim(); 
      $("#postal").val(address1 + "\n" + address2); 
     } 
    }); 
}); 

(我試圖用的jsfiddle或類似的一個例子,但那些業務沒有玩的地圖API不錯)。

最重要的部分是:

  • 使用功能爲source參數自動完成。在該功能中,使用google.maps.Geocoder對輸入地址進行地址編碼。
  • 在地理編碼請求的回調中,使用格式化地址更新自動填充選項。

用戶之後選擇一個地址:

  • 拆分由逗號地址。
  • 取出地址的第一部分並將其與最後部分組合。
  • 用結果字符串填充#postal字段。
+0

好的,你釘了它的人!這正是我想要做的! – simian

0

您將需要一個地址數據庫來做到這一點。您可以購買一個,或者可以找到一個類似於:http://www2.royalmail.com/marketing-services/address-management-unit/address-data-products/postcode-address-file-paf?campaignid=paf_redirect

我會是一個可怕的想法,在每次用戶開始輸入時都會在自動完成功能中運行地理編碼器。這些網站中的大多數都有地理編碼查詢的每日限制,否則您必須開始付款。

+0

谷歌地圖API每天的** 25,000 **請求限制。也許OP不需要擔心這個限制。無論哪種方式,OP的戰略的這一部分似乎超出了這個問題的範圍(在我看來)。此外,OP可能實際上已經支付了商業地圖API密鑰,使得這一點完全沒有意義。 –

+0

我想是的,這是一個有效的觀點。 –

+0

是的,我認爲地理編碼谷歌地圖API是每天1000比我需要更多。我只預計每天使用10次左右...所以我沒有經過創建和獲取大型數據庫的工作,而是希望利用這個現有的數據庫。 – simian