diff --git a/jquery.geocomplete.js b/jquery.geocomplete.js index 7679262..14b9181 100644 --- a/jquery.geocomplete.js +++ b/jquery.geocomplete.js @@ -180,14 +180,17 @@ var options = { types: this.options.types, - bounds: this.options.bounds === true ? null : this.options.bounds, - componentRestrictions: this.options.componentRestrictions + bounds: this.options.bounds === true ? null : this.options.bounds }; if (this.options.country){ options.componentRestrictions = {country: this.options.country}; } + if(this.options.fields) { + options.fields = this.options.fields; + } + this.autocomplete = new google.maps.places.Autocomplete( this.input, options ); @@ -330,11 +333,17 @@ }); }, + findById: function(placeId){ + this.geocode({ + placeId: placeId + }); + }, + // Requests details about a given location. // Additionally it will bias the requests to the provided bounds. geocode: function(request){ // Don't geocode if the requested address is empty - if (!request.address) { + if (!request.address && !request.placeId) { return; } if (this.options.bounds && !request.bounds){ @@ -373,7 +382,11 @@ firstResult += " - " + $span2; } - this.$input.val(firstResult); + if(!!firstResult) { + this.$input.val(firstResult); + } else { + firstResult = this.$input.val(); + } return firstResult; }, @@ -536,21 +549,38 @@ // Update the plugin after the user has selected an autocomplete entry. // If the place has no geometry it passes it to the geocoder. - placeChanged: function(){ + placeChanged: function() { var place = this.autocomplete.getPlace(); this.selected = true; - if (!place.geometry){ + if (!place.geometry) { if (this.options.autoselect) { - // Automatically selects the highlighted item or the first item from the - // suggestions list. - var autoSelection = this.selectFirstResult(); - this.find(autoSelection); + var autoCompleteService = this.getAutoCompleteService(); + autoCompleteService.getPlacePredictions({ + input: this.$input.val().split(',')[0] + }, $.proxy(this.placePredictionChange, this)) } } else { - // Use the input text if it already gives geometry. this.update(place); } + }, + + placePredictionChange: function(result, status) { + if (status == google.maps.places.PlacesServiceStatus.OK) { + if(result.length > 0) { + this.findById(result[0].place_id); + } + } else { + this.trigger("geocode:error", status); + } + }, + + getAutoCompleteService: function() { + if (!this.autocompleteService) { + return this.autocompleteService = new google.maps.places.AutocompleteService(); + } else { + return this.autocompleteService; + } } }); diff --git a/jquery.geocomplete.min.js b/jquery.geocomplete.min.js index 31349e0..a41c378 100644 --- a/jquery.geocomplete.min.js +++ b/jquery.geocomplete.min.js @@ -5,4 +5,4 @@ * @author Ubilabs http://ubilabs.net, 2016 * @license MIT License */ -(function($,window,document,undefined){var defaults={bounds:true,country:null,map:false,details:false,detailsAttribute:"name",detailsScope:null,autoselect:true,location:false,mapOptions:{zoom:14,scrollwheel:false,mapTypeId:"roadmap"},markerOptions:{draggable:false},maxZoom:16,types:["geocode"],blur:false,geocodeAfterResult:false,restoreValueAfterBlur:false};var componentTypes=("street_address route intersection political "+"country administrative_area_level_1 administrative_area_level_2 "+"administrative_area_level_3 colloquial_area locality sublocality "+"neighborhood premise subpremise postal_code natural_feature airport "+"park point_of_interest post_box street_number floor room "+"lat lng viewport location "+"formatted_address location_type bounds").split(" ");var placesDetails=("id place_id url website vicinity reference name rating "+"international_phone_number icon formatted_phone_number").split(" ");function GeoComplete(input,options){this.options=$.extend(true,{},defaults,options);if(options&&options.types){this.options.types=options.types}this.input=input;this.$input=$(input);this._defaults=defaults;this._name="geocomplete";this.init()}$.extend(GeoComplete.prototype,{init:function(){this.initMap();this.initMarker();this.initGeocoder();this.initDetails();this.initLocation()},initMap:function(){if(!this.options.map){return}if(typeof this.options.map.setCenter=="function"){this.map=this.options.map;return}this.map=new google.maps.Map($(this.options.map)[0],this.options.mapOptions);google.maps.event.addListener(this.map,"click",$.proxy(this.mapClicked,this));google.maps.event.addListener(this.map,"dragend",$.proxy(this.mapDragged,this));google.maps.event.addListener(this.map,"idle",$.proxy(this.mapIdle,this));google.maps.event.addListener(this.map,"zoom_changed",$.proxy(this.mapZoomed,this))},initMarker:function(){if(!this.map){return}var options=$.extend(this.options.markerOptions,{map:this.map});if(options.disabled){return}this.marker=new google.maps.Marker(options);google.maps.event.addListener(this.marker,"dragend",$.proxy(this.markerDragged,this))},initGeocoder:function(){var selected=false;var options={types:this.options.types,bounds:this.options.bounds===true?null:this.options.bounds,componentRestrictions:this.options.componentRestrictions};if(this.options.country){options.componentRestrictions={country:this.options.country}}this.autocomplete=new google.maps.places.Autocomplete(this.input,options);this.geocoder=new google.maps.Geocoder;if(this.map&&this.options.bounds===true){this.autocomplete.bindTo("bounds",this.map)}google.maps.event.addListener(this.autocomplete,"place_changed",$.proxy(this.placeChanged,this));this.$input.on("keypress."+this._name,function(event){if(event.keyCode===13){return false}});if(this.options.geocodeAfterResult===true){this.$input.bind("keypress."+this._name,$.proxy(function(){if(event.keyCode!=9&&this.selected===true){this.selected=false}},this))}this.$input.bind("geocode."+this._name,$.proxy(function(){this.find()},this));this.$input.bind("geocode:result."+this._name,$.proxy(function(){this.lastInputVal=this.$input.val()},this));if(this.options.blur===true){this.$input.on("blur."+this._name,$.proxy(function(){if(this.options.geocodeAfterResult===true&&this.selected===true){return}if(this.options.restoreValueAfterBlur===true&&this.selected===true){setTimeout($.proxy(this.restoreLastValue,this),0)}else{this.find()}},this))}},initDetails:function(){if(!this.options.details){return}if(this.options.detailsScope){var $details=$(this.input).parents(this.options.detailsScope).find(this.options.details)}else{var $details=$(this.options.details)}var attribute=this.options.detailsAttribute,details={};function setDetail(value){details[value]=$details.find("["+attribute+"="+value+"]")}$.each(componentTypes,function(index,key){setDetail(key);setDetail(key+"_short")});$.each(placesDetails,function(index,key){setDetail(key)});this.$details=$details;this.details=details},initLocation:function(){var location=this.options.location,latLng;if(!location){return}if(typeof location=="string"){this.find(location);return}if(location instanceof Array){latLng=new google.maps.LatLng(location[0],location[1])}if(location instanceof google.maps.LatLng){latLng=location}if(latLng){if(this.map){this.map.setCenter(latLng)}if(this.marker){this.marker.setPosition(latLng)}}},destroy:function(){if(this.map){google.maps.event.clearInstanceListeners(this.map);google.maps.event.clearInstanceListeners(this.marker)}this.autocomplete.unbindAll();google.maps.event.clearInstanceListeners(this.autocomplete);google.maps.event.clearInstanceListeners(this.input);this.$input.removeData();this.$input.off(this._name);this.$input.unbind("."+this._name)},find:function(address){this.geocode({address:address||this.$input.val()})},geocode:function(request){if(!request.address){return}if(this.options.bounds&&!request.bounds){if(this.options.bounds===true){request.bounds=this.map&&this.map.getBounds()}else{request.bounds=this.options.bounds}}if(this.options.country){request.region=this.options.country}this.geocoder.geocode(request,$.proxy(this.handleGeocode,this))},selectFirstResult:function(){var selected="";if($(".pac-item-selected")[0]){selected="-selected"}var $span1=$(".pac-container:visible .pac-item"+selected+":first span:nth-child(2)").text();var $span2=$(".pac-container:visible .pac-item"+selected+":first span:nth-child(3)").text();var firstResult=$span1;if($span2){firstResult+=" - "+$span2}this.$input.val(firstResult);return firstResult},restoreLastValue:function(){if(this.lastInputVal){this.$input.val(this.lastInputVal)}},handleGeocode:function(results,status){if(status===google.maps.GeocoderStatus.OK){var result=results[0];this.$input.val(result.formatted_address);this.update(result);if(results.length>1){this.trigger("geocode:multiple",results)}}else{this.trigger("geocode:error",status)}},trigger:function(event,argument){this.$input.trigger(event,[argument])},center:function(geometry){if(geometry.viewport){this.map.fitBounds(geometry.viewport);if(this.map.getZoom()>this.options.maxZoom){this.map.setZoom(this.options.maxZoom)}}else{this.map.setZoom(this.options.maxZoom);this.map.setCenter(geometry.location)}if(this.marker){this.marker.setPosition(geometry.location);this.marker.setAnimation(this.options.markerOptions.animation)}},update:function(result){if(this.map){this.center(result.geometry)}if(this.$details){this.fillDetails(result)}this.trigger("geocode:result",result)},fillDetails:function(result){var data={},geometry=result.geometry,viewport=geometry.viewport,bounds=geometry.bounds;$.each(result.address_components,function(index,object){var name=object.types[0];$.each(object.types,function(index,name){data[name]=object.long_name;data[name+"_short"]=object.short_name})});$.each(placesDetails,function(index,key){data[key]=result[key]});$.extend(data,{formatted_address:result.formatted_address,location_type:geometry.location_type||"PLACES",viewport:viewport,bounds:bounds,location:geometry.location,lat:geometry.location.lat(),lng:geometry.location.lng()});$.each(this.details,$.proxy(function(key,$detail){var value=data[key];this.setDetail($detail,value)},this));this.data=data},setDetail:function($element,value){if(value===undefined){value=""}else if(typeof value.toUrlValue=="function"){value=value.toUrlValue()}if($element.is(":input")){$element.val(value)}else{$element.text(value)}},markerDragged:function(event){this.trigger("geocode:dragged",event.latLng)},mapClicked:function(event){this.trigger("geocode:click",event.latLng)},mapDragged:function(event){this.trigger("geocode:mapdragged",this.map.getCenter())},mapIdle:function(event){this.trigger("geocode:idle",this.map.getCenter())},mapZoomed:function(event){this.trigger("geocode:zoom",this.map.getZoom())},resetMarker:function(){this.marker.setPosition(this.data.location);this.setDetail(this.details.lat,this.data.location.lat());this.setDetail(this.details.lng,this.data.location.lng())},placeChanged:function(){var place=this.autocomplete.getPlace();this.selected=true;if(!place.geometry){if(this.options.autoselect){var autoSelection=this.selectFirstResult();this.find(autoSelection)}}else{this.update(place)}}});$.fn.geocomplete=function(options){var attribute="plugin_geocomplete";if(typeof options=="string"){var instance=$(this).data(attribute)||$(this).geocomplete().data(attribute),prop=instance[options];if(typeof prop=="function"){prop.apply(instance,Array.prototype.slice.call(arguments,1));return $(this)}else{if(arguments.length==2){prop=arguments[1]}return prop}}else{return this.each(function(){var instance=$.data(this,attribute);if(!instance){instance=new GeoComplete(this,options);$.data(this,attribute,instance)}})}}})(jQuery,window,document); +!function(t,e,i,o){var s={bounds:!0,country:null,map:!1,details:!1,detailsAttribute:"name",detailsScope:null,autoselect:!0,location:!1,mapOptions:{zoom:14,scrollwheel:!1,mapTypeId:"roadmap"},markerOptions:{draggable:!1},maxZoom:16,types:["geocode"],blur:!1,geocodeAfterResult:!1,restoreValueAfterBlur:!1},n="street_address route intersection political country administrative_area_level_1 administrative_area_level_2 administrative_area_level_3 colloquial_area locality sublocality neighborhood premise subpremise postal_code natural_feature airport park point_of_interest post_box street_number floor room lat lng viewport location formatted_address location_type bounds".split(" "),a="id place_id url website vicinity reference name rating international_phone_number icon formatted_phone_number".split(" ");function r(e,i){this.options=t.extend(!0,{},s,i),i&&i.types&&(this.options.types=i.types),this.input=e,this.$input=t(e),this._defaults=s,this._name="geocomplete",this.init()}t.extend(r.prototype,{init:function(){this.initMap(),this.initMarker(),this.initGeocoder(),this.initDetails(),this.initLocation()},initMap:function(){this.options.map&&("function"!=typeof this.options.map.setCenter?(this.map=new google.maps.Map(t(this.options.map)[0],this.options.mapOptions),google.maps.event.addListener(this.map,"click",t.proxy(this.mapClicked,this)),google.maps.event.addListener(this.map,"dragend",t.proxy(this.mapDragged,this)),google.maps.event.addListener(this.map,"idle",t.proxy(this.mapIdle,this)),google.maps.event.addListener(this.map,"zoom_changed",t.proxy(this.mapZoomed,this))):this.map=this.options.map)},initMarker:function(){if(this.map){var e=t.extend(this.options.markerOptions,{map:this.map});e.disabled||(this.marker=new google.maps.Marker(e),google.maps.event.addListener(this.marker,"dragend",t.proxy(this.markerDragged,this)))}},initGeocoder:function(){var e={types:this.options.types,bounds:!0===this.options.bounds?null:this.options.bounds};this.options.country&&(e.componentRestrictions={country:this.options.country}),this.options.fields&&(e.fields=this.options.fields),this.autocomplete=new google.maps.places.Autocomplete(this.input,e),this.geocoder=new google.maps.Geocoder,this.map&&!0===this.options.bounds&&this.autocomplete.bindTo("bounds",this.map),google.maps.event.addListener(this.autocomplete,"place_changed",t.proxy(this.placeChanged,this)),this.$input.on("keypress."+this._name,function(t){if(13===t.keyCode)return!1}),!0===this.options.geocodeAfterResult&&this.$input.bind("keypress."+this._name,t.proxy(function(){9!=event.keyCode&&!0===this.selected&&(this.selected=!1)},this)),this.$input.bind("geocode."+this._name,t.proxy(function(){this.find()},this)),this.$input.bind("geocode:result."+this._name,t.proxy(function(){this.lastInputVal=this.$input.val()},this)),!0===this.options.blur&&this.$input.on("blur."+this._name,t.proxy(function(){!0===this.options.geocodeAfterResult&&!0===this.selected||(!0===this.options.restoreValueAfterBlur&&!0===this.selected?setTimeout(t.proxy(this.restoreLastValue,this),0):this.find())},this))},initDetails:function(){if(this.options.details){if(this.options.detailsScope)var e=t(this.input).parents(this.options.detailsScope).find(this.options.details);else e=t(this.options.details);var i=this.options.detailsAttribute,o={};t.each(n,function(t,e){s(e),s(e+"_short")}),t.each(a,function(t,e){s(e)}),this.$details=e,this.details=o}function s(t){o[t]=e.find("["+i+"="+t+"]")}},initLocation:function(){var t,e=this.options.location;e&&("string"!=typeof e?(e instanceof Array&&(t=new google.maps.LatLng(e[0],e[1])),e instanceof google.maps.LatLng&&(t=e),t&&(this.map&&this.map.setCenter(t),this.marker&&this.marker.setPosition(t))):this.find(e))},destroy:function(){this.map&&(google.maps.event.clearInstanceListeners(this.map),google.maps.event.clearInstanceListeners(this.marker)),this.autocomplete.unbindAll(),google.maps.event.clearInstanceListeners(this.autocomplete),google.maps.event.clearInstanceListeners(this.input),this.$input.removeData(),this.$input.off(this._name),this.$input.unbind("."+this._name)},find:function(t){this.geocode({address:t||this.$input.val()})},findById:function(t){this.geocode({placeId:t})},geocode:function(e){(e.address||e.placeId)&&(this.options.bounds&&!e.bounds&&(!0===this.options.bounds?e.bounds=this.map&&this.map.getBounds():e.bounds=this.options.bounds),this.options.country&&(e.region=this.options.country),this.geocoder.geocode(e,t.proxy(this.handleGeocode,this)))},selectFirstResult:function(){var e="";t(".pac-item-selected")[0]&&(e="-selected");var i=t(".pac-container:visible .pac-item"+e+":first span:nth-child(2)").text(),o=t(".pac-container:visible .pac-item"+e+":first span:nth-child(3)").text(),s=i;return o&&(s+=" - "+o),s?this.$input.val(s):s=this.$input.val(),s},restoreLastValue:function(){this.lastInputVal&&this.$input.val(this.lastInputVal)},handleGeocode:function(t,e){if(e===google.maps.GeocoderStatus.OK){var i=t[0];this.$input.val(i.formatted_address),this.update(i),t.length>1&&this.trigger("geocode:multiple",t)}else this.trigger("geocode:error",e)},trigger:function(t,e){this.$input.trigger(t,[e])},center:function(t){t.viewport?(this.map.fitBounds(t.viewport),this.map.getZoom()>this.options.maxZoom&&this.map.setZoom(this.options.maxZoom)):(this.map.setZoom(this.options.maxZoom),this.map.setCenter(t.location)),this.marker&&(this.marker.setPosition(t.location),this.marker.setAnimation(this.options.markerOptions.animation))},update:function(t){this.map&&this.center(t.geometry),this.$details&&this.fillDetails(t),this.trigger("geocode:result",t)},fillDetails:function(e){var i={},o=e.geometry,s=o.viewport,n=o.bounds;t.each(e.address_components,function(e,o){o.types[0];t.each(o.types,function(t,e){i[e]=o.long_name,i[e+"_short"]=o.short_name})}),t.each(a,function(t,o){i[o]=e[o]}),t.extend(i,{formatted_address:e.formatted_address,location_type:o.location_type||"PLACES",viewport:s,bounds:n,location:o.location,lat:o.location.lat(),lng:o.location.lng()}),t.each(this.details,t.proxy(function(t,e){var o=i[t];this.setDetail(e,o)},this)),this.data=i},setDetail:function(t,e){void 0===e?e="":"function"==typeof e.toUrlValue&&(e=e.toUrlValue()),t.is(":input")?t.val(e):t.text(e)},markerDragged:function(t){this.trigger("geocode:dragged",t.latLng)},mapClicked:function(t){this.trigger("geocode:click",t.latLng)},mapDragged:function(t){this.trigger("geocode:mapdragged",this.map.getCenter())},mapIdle:function(t){this.trigger("geocode:idle",this.map.getCenter())},mapZoomed:function(t){this.trigger("geocode:zoom",this.map.getZoom())},resetMarker:function(){this.marker.setPosition(this.data.location),this.setDetail(this.details.lat,this.data.location.lat()),this.setDetail(this.details.lng,this.data.location.lng())},placeChanged:function(){var e=this.autocomplete.getPlace();(this.selected=!0,e.geometry)?this.update(e):this.options.autoselect&&this.getAutoCompleteService().getPlacePredictions({input:this.$input.val().split(",")[0]},t.proxy(this.placePredictionChange,this))},placePredictionChange:function(t,e){e==google.maps.places.PlacesServiceStatus.OK?t.length>0&&this.findById(t[0].place_id):this.trigger("geocode:error",e)},getAutoCompleteService:function(){return this.autocompleteService?this.autocompleteService:this.autocompleteService=new google.maps.places.AutocompleteService}}),t.fn.geocomplete=function(e){var i="plugin_geocomplete";if("string"==typeof e){var o=t(this).data(i)||t(this).geocomplete().data(i),s=o[e];return"function"==typeof s?(s.apply(o,Array.prototype.slice.call(arguments,1)),t(this)):(2==arguments.length&&(s=arguments[1]),s)}return this.each(function(){var o=t.data(this,i);o||(o=new r(this,e),t.data(this,i,o))})}}(jQuery,window,document); \ No newline at end of file