Saturday, April 14, 2018

Autocomplete address field trigger to closest listed GEO location

Leave a Comment

Right now, the code uses the browser's GEO location to determine, where the user is located, and calculates the distances from each location in the location list to the user. It sorts the list in the drop-down and requires the user to manually select a location there (this will be most of the time the shortest location on top of the sorted list).

By clicking on the button below the drop-down after the selection was made, a link will be executed that is associated with the user's selection.

I want to replace the code that automatically determines the location of the user with the Google API address field. The user should be required to type in an address, select one of the auto-populated options that is being displayed, and get forwarded to the link associated with the location closest to the selected address. The events that get triggered after selecting an address:

  1. Distances are being calculated between the selected address and the locations in the location list
  2. The closest location will be determined (the user has no say in this)
  3. The link associated with the closest location will be executed (a href). The visual end result should be just one address field. I included the drop-down and button because I think this can be done with much of the underlying code, even though I have not been able to do so yet.

Thanks Ali for uploading the code into a fiddle:

https://fiddle.jshell.net/ali_soltani/5h283178/4/

1 Answers

Answers 1

I was able to come up with a solution that uses JSON and takes "just one address field", as I was trying to explain. I am not a coder (just trying to become one) and still have a hard time expression myself correctly, but I hope this solution is useful to someone. Please make sure to paste your own Google API key on the button where it says "PASTE_YOUR_GOOGLE_API_KEY_HERE" in order for it to run.

You can obtain a key here:https://developers.google.com/maps/documentation/javascript/get-api-key

My solution:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>      <script>   var elem1 = {id:"New York",link:"http://bla1.com",longitude:-73.935242,latitude:40.730610};   var elem2 = {id:"Los Angeles",link:"http://bla2.com",longitude:-118.243683,latitude:34.052235};   var elem3 = {id:"Detroit_whoop_whoop",link:"http://bla3.com",longitude:-83.045753,latitude:42.331429};     var elemArry = [elem1,elem2,elem3];    function jDistance(lon1, lat1,elm ) {  	var lon2 = elm.longitude;  	var lat2 = elm.latitude;  	var R = 6371; // Radius of the earth in km    var dLat = (lat2-lat1).toRad();  // Javascript functions in radians    var dLon = (lon2-lon1).toRad();     var a = Math.sin(dLat/2) * Math.sin(dLat/2) +            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *             Math.sin(dLon/2) * Math.sin(dLon/2);     var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));     var d = R * c; // Distance in km  	//console.log("distance "+d);  	elm.distance = d;    return d;      }      /** Converts numeric degrees to radians */  if (typeof(Number.prototype.toRad) === "undefined") {    Number.prototype.toRad = function() {      return this * Math.PI / 180;    }  }    function setandsortPosition(pos_1) {      console.log("navigator.geolocation start ");     console.log("pos_1.lon " +pos_1.lon);     console.log("pos_1.lat " +pos_1.lat);     for (var elm in elemArry){  	jDistance(pos_1.lon, pos_1.lat,elemArry[elm]);   }  	elemArry.sort((a, b) => parseFloat(a.distance) - parseFloat(b.distance));    window.location.href = elemArry[0].link;  }    </script>    <div id="locationField"><input id="autocomplete" placeholder="&gt; Enter your address here &lt;" type="text" style="text-align: center;"  /></div>    <script>          var placeSearch, autocomplete;        var componentForm = {          street_number: 'short_name',          route: 'long_name',          locality: 'long_name',          administrative_area_level_1: 'short_name',          country: 'long_name',          postal_code: 'short_name'        };          function initAutocomplete() {                   autocomplete = new google.maps.places.Autocomplete(              /** @type {!HTMLInputElement} */(document.getElementById('autocomplete')),              {types: ['geocode']});                     autocomplete.addListener('place_changed', fillInAddress);        }          function fillInAddress() {                    var place = autocomplete.getPlace();            for (var component in componentForm) {          console.log("component "+ component);          //  document.getElementById(component).value = '';         //   document.getElementById(component).disabled = false;          }                      for (var i = 0; i < place.address_components.length; i++) {            var addressType = place.address_components[i].types[0];            if (componentForm[addressType]) {              var val = place.address_components[i][componentForm[addressType]];              if (val != null){              console.log("addressType "+addressType);              //document.getElementById(addressType).value = val;              }                          }          }                      console.log("lat "+place.geometry.location.lat());             console.log("lng "+ place.geometry.location.lng());             var geolocation = {                lat: place.geometry.location.lat(),                lon: place.geometry.location.lng()              };               setandsortPosition(geolocation) ;            }        </script><script src="https://maps.googleapis.com/maps/api/js?key=PASTE_YOUR_GOOGLE_API_HERE&amp;libraries=places&amp;callback=initAutocomplete" async="" defer="defer"></script>

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment