Update locationpicker.jquery.js

This commit is contained in:
Nabil Kadimi
2018-09-12 19:43:47 +01:00
committed by GitHub
parent 61bab3cbc8
commit 15369f23ac

View File

@@ -1,44 +1,14 @@
/* /*! jquery-locationpicker - v0.1.16 - 2017-10-02 */
* File: locationpicker.jquery.js (function($) {
* Version: 0.1.6
* Author: Dmitry Berezovsky, Logicify (http://logicify.com/)
* Info: http://logicify.github.io/jquery-locationpicker-plugin/
*
* Copyright 2013 Logicify
*
* The MIT License (MIT)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function ( $ ) {
/**
* Holds google map object and related utility entities.
* @constructor
*/
function GMapContext(domElement, options) { function GMapContext(domElement, options) {
var _map = new google.maps.Map(domElement, options); var _map = new google.maps.Map(domElement, options);
var _marker = new google.maps.Marker({ var _marker = new google.maps.Marker({
position: new google.maps.LatLng(54.19335, -3.92695), position: new google.maps.LatLng(54.19335, -3.92695),
map: _map, map: _map,
title: "Drag Me", title: "Drag Me",
draggable: true visible: options.markerVisible,
draggable: options.markerDraggable,
icon: options.markerIcon !== undefined ? options.markerIcon : undefined
}); });
return { return {
map: _map, map: _map,
@@ -47,23 +17,23 @@
location: _marker.position, location: _marker.position,
radius: options.radius, radius: options.radius,
locationName: options.locationName, locationName: options.locationName,
addressComponents: {
formatted_address: null,
addressLine1: null,
addressLine2: null,
streetName: null,
streetNumber: null,
city: null,
district: null,
state: null,
stateOrProvince: null
},
settings: options.settings, settings: options.settings,
domContainer: domElement, domContainer: domElement,
geodecoder: new google.maps.Geocoder() geodecoder: new google.maps.Geocoder()
};
} }
}
// Utility functions for Google Map Manipulations
var GmUtility = { var GmUtility = {
/**
* Draw a circle over the the map. Returns circle object.
* Also writes new circle object in gmapContext.
*
* @param center - LatLng of the center of the circle
* @param radius - radius in meters
* @param gmapContext - context
* @param options
*/
drawCircle: function(gmapContext, center, radius, options) { drawCircle: function(gmapContext, center, radius, options) {
if (gmapContext.circle != null) { if (gmapContext.circle != null) {
gmapContext.circle.setMap(null); gmapContext.circle.setMap(null);
@@ -72,10 +42,10 @@
radius *= 1; radius *= 1;
options = $.extend({ options = $.extend({
strokeColor: "#0000FF", strokeColor: "#0000FF",
strokeOpacity: 0.35, strokeOpacity: .35,
strokeWeight: 2, strokeWeight: 2,
fillColor: "#0000FF", fillColor: "#0000FF",
fillOpacity: 0.20 fillOpacity: .2
}, options); }, options);
options.map = gmapContext.map; options.map = gmapContext.map;
options.radius = radius; options.radius = radius;
@@ -85,125 +55,214 @@
} }
return null; return null;
}, },
/**
*
* @param gMapContext
* @param location
* @param callback
*/
setPosition: function(gMapContext, location, callback) { setPosition: function(gMapContext, location, callback) {
gMapContext.location = location; gMapContext.location = location;
gMapContext.marker.setPosition(location); gMapContext.marker.setPosition(location);
gMapContext.map.panTo(location); gMapContext.map.panTo(location);
this.drawCircle(gMapContext, location, gMapContext.radius, {}); this.drawCircle(gMapContext, location, gMapContext.radius, {});
if (gMapContext.settings.enableReverseGeocode) { if (gMapContext.settings.enableReverseGeocode) {
gMapContext.geodecoder.geocode({latLng: gMapContext.location}, function(results, status){ this.updateLocationName(gMapContext, callback);
if (status == google.maps.GeocoderStatus.OK && results.length > 0){ } else {
gMapContext.locationName = results[0].formatted_address;
}
if (callback) { if (callback) {
callback.call(this, gMapContext); callback.call(this, gMapContext);
} }
}); }
} else { },
locationFromLatLng: function(lnlg) {
return {
latitude: lnlg.lat(),
longitude: lnlg.lng()
};
},
addressByFormat: function(addresses, format) {
var result = null;
for (var i = addresses.length - 1; i >= 0; i--) {
if (addresses[i].types.indexOf(format) >= 0) {
result = addresses[i];
}
}
return result || addresses[0];
},
updateLocationName: function(gmapContext, callback) {
gmapContext.geodecoder.geocode({
latLng: gmapContext.marker.position
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
var address = GmUtility.addressByFormat(results, gmapContext.settings.addressFormat);
gmapContext.locationName = address.formatted_address;
gmapContext.addressComponents = GmUtility.address_component_from_google_geocode(address.address_components);
} else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
return setTimeout(function() {
GmUtility.updateLocationName(gmapContext, callback);
}, 1e3);
}
if (callback) { if (callback) {
callback.call(this, gmapContext); callback.call(this, gmapContext);
} }
} });
}, },
locationFromLatLng: function(lnlg) { address_component_from_google_geocode: function(address_components) {
return {latitude: lnlg.lat(), longitude: lnlg.lng()} var result = {};
for (var i = address_components.length - 1; i >= 0; i--) {
var component = address_components[i];
if (component.types.indexOf("postal_code") >= 0) {
result.postalCode = component.short_name;
} else if (component.types.indexOf("street_number") >= 0) {
result.streetNumber = component.short_name;
} else if (component.types.indexOf("route") >= 0) {
result.streetName = component.short_name;
} else if (component.types.indexOf("locality") >= 0) {
result.city = component.short_name;
} else if (component.types.indexOf("sublocality") >= 0) {
result.district = component.short_name;
} else if (component.types.indexOf("administrative_area_level_1") >= 0) {
result.stateOrProvince = component.short_name;
} else if (component.types.indexOf("country") >= 0) {
result.country = component.short_name;
} }
} }
result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
result.addressLine2 = "";
return result;
}
};
function isPluginApplied(domObj) { function isPluginApplied(domObj) {
return getContextForElement(domObj) != undefined; return getContextForElement(domObj) != undefined;
} }
function getContextForElement(domObj) { function getContextForElement(domObj) {
return $(domObj).data("locationpicker"); return $(domObj).data("locationpicker");
} }
function updateInputValues(inputBinding, gmapContext) {
function updateInputValues(inputBinding, gmapContext){
if (!inputBinding) return; if (!inputBinding) return;
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location); var currentLocation = GmUtility.locationFromLatLng(gmapContext.marker.position);
if (inputBinding.latitudeInput) { if (inputBinding.latitudeInput) {
inputBinding.latitudeInput.val(currentLocation.latitude); inputBinding.latitudeInput.val(currentLocation.latitude).change();
} }
if (inputBinding.longitudeInput) { if (inputBinding.longitudeInput) {
inputBinding.longitudeInput.val(currentLocation.longitude); inputBinding.longitudeInput.val(currentLocation.longitude).change();
} }
if (inputBinding.radiusInput) { if (inputBinding.radiusInput) {
inputBinding.radiusInput.val(gmapContext.radius); inputBinding.radiusInput.val(gmapContext.radius).change();
} }
if (inputBinding.locationNameInput) { if (inputBinding.locationNameInput) {
inputBinding.locationNameInput.val(gmapContext.locationName); inputBinding.locationNameInput.val(gmapContext.locationName).change();
} }
} }
function setupInputListenersInput(inputBinding, gmapContext) { function setupInputListenersInput(inputBinding, gmapContext) {
if (inputBinding) { if (inputBinding) {
if (inputBinding.radiusInput){ if (inputBinding.radiusInput) {
inputBinding.radiusInput.on("change", function() { inputBinding.radiusInput.on("change", function(e) {
gmapContext.radius = $(this).val(); var radiusInputValue = $(this).val();
GmUtility.setPosition(gmapContext, gmapContext.location, function(context){ if (!e.originalEvent || isNaN(radiusInputValue)) {
context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false); return;
}
gmapContext.radius = radiusInputValue;
GmUtility.setPosition(gmapContext, gmapContext.location, function(context) {
context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
}); });
}); });
} }
if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) { if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0)); var blur = false;
google.maps.event.addListener(gmapContext.autocomplete, 'place_changed', function() { gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0), gmapContext.settings.autocompleteOptions);
google.maps.event.addListener(gmapContext.autocomplete, "place_changed", function() {
blur = false;
var place = gmapContext.autocomplete.getPlace(); var place = gmapContext.autocomplete.getPlace();
if (!place.geometry) { if (!place.geometry) {
gmapContext.onlocationnotfound(); gmapContext.settings.onlocationnotfound(place.name);
return; return;
} }
GmUtility.setPosition(gmapContext, place.geometry.location, function(context) { GmUtility.setPosition(gmapContext, place.geometry.location, function(context) {
updateInputValues(inputBinding, context); updateInputValues(inputBinding, context);
context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false); context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
}); });
}); });
if (gmapContext.settings.enableAutocompleteBlur) {
inputBinding.locationNameInput.on("change", function(e) {
if (!e.originalEvent) {
return;
}
blur = true;
});
inputBinding.locationNameInput.on("blur", function(e) {
if (!e.originalEvent) {
return;
}
setTimeout(function() {
var address = $(inputBinding.locationNameInput).val();
if (address.length > 5 && blur) {
blur = false;
gmapContext.geodecoder.geocode({
address: address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results && results.length) {
GmUtility.setPosition(gmapContext, results[0].geometry.location, function(context) {
updateInputValues(inputBinding, context);
context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
});
}
});
}
}, 1e3);
});
}
} }
if (inputBinding.latitudeInput) { if (inputBinding.latitudeInput) {
inputBinding.latitudeInput.on("change", function() { inputBinding.latitudeInput.on("change", function(e) {
GmUtility.setPosition(gmapContext, new google.maps.LatLng($(this).val(), gmapContext.location.lng()), function(context){ var latitudeInputValue = $(this).val();
context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false); if (!e.originalEvent || isNaN(latitudeInputValue)) {
return;
}
GmUtility.setPosition(gmapContext, new google.maps.LatLng(latitudeInputValue, gmapContext.location.lng()), function(context) {
context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
}); });
}); });
} }
if (inputBinding.longitudeInput) { if (inputBinding.longitudeInput) {
inputBinding.longitudeInput.on("change", function() { inputBinding.longitudeInput.on("change", function(e) {
GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), $(this).val()), function(context){ var longitudeInputValue = $(this).val();
context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false); if (!e.originalEvent || isNaN(longitudeInputValue)) {
return;
}
GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), longitudeInputValue), function(context) {
context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
}); });
}); });
} }
} }
} }
function autosize(gmapContext) {
/** google.maps.event.trigger(gmapContext.map, "resize");
* Initialization: setTimeout(function() {
* $("#myMap").locationpicker(options); gmapContext.map.setCenter(gmapContext.marker.position);
* @param options }, 300);
* @param params }
* @returns {*} function updateMap(gmapContext, $target, options) {
*/ var settings = $.extend({}, $.fn.locationpicker.defaults, options), latNew = settings.location.latitude, lngNew = settings.location.longitude, radiusNew = settings.radius, latOld = gmapContext.settings.location.latitude, lngOld = gmapContext.settings.location.longitude, radiusOld = gmapContext.settings.radius;
$.fn.locationpicker = function( options, params ) { if (latNew == latOld && lngNew == lngOld && radiusNew == radiusOld) return;
if (typeof options == 'string') { // Command provided gmapContext.settings.location.latitude = latNew;
gmapContext.settings.location.longitude = lngNew;
gmapContext.radius = radiusNew;
GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.settings.location.latitude, gmapContext.settings.location.longitude), function(context) {
setupInputListenersInput(gmapContext.settings.inputBinding, gmapContext);
context.settings.oninitialized($target);
});
}
$.fn.locationpicker = function(options, params) {
if (typeof options == "string") {
var _targetDomElement = this.get(0); var _targetDomElement = this.get(0);
// Plug-in is not applied - nothing to do.
if (!isPluginApplied(_targetDomElement)) return; if (!isPluginApplied(_targetDomElement)) return;
var gmapContext = getContextForElement(_targetDomElement); var gmapContext = getContextForElement(_targetDomElement);
switch (options) { switch (options) {
case "location": case "location":
if (params == undefined) { // Getter if (params == undefined) {
var location = GmUtility.locationFromLatLng(gmapContext.location); var location = GmUtility.locationFromLatLng(gmapContext.location);
location.radius = gmapContext.radius; location.radius = gmapContext.radius;
location.name = gmapContext.locationName; location.name = gmapContext.locationName;
return location; return location;
} else { // Setter } else {
if (params.radius) { if (params.radius) {
gmapContext.radius = params.radius; gmapContext.radius = params.radius;
} }
@@ -212,72 +271,112 @@
}); });
} }
break; break;
case "subscribe": case "subscribe":
/** if (params == undefined) {
* Provides interface for subscribing for GoogleMap events.
* See Google API documentation for details.
* Parameters:
* - event: string, name of the event
* - callback: function, callback function to be invoked
*/
if (options == undefined) { // Getter is not available
return null; return null;
} else { } else {
var event = params.event; var event = params.event;
var callback = params.callback; var callback = params.callback;
if (!event || ! callback) { if (!event || !callback) {
console.error("LocationPicker: Invalid arguments for method \"subscribe\"") console.error('LocationPicker: Invalid arguments for method "subscribe"');
return null; return null;
} }
google.maps.event.addListener(gmapContext.map, event, callback); google.maps.event.addListener(gmapContext.map, event, callback);
} }
break; break;
case "map":
if (params == undefined) {
var locationObj = GmUtility.locationFromLatLng(gmapContext.location);
locationObj.formattedAddress = gmapContext.locationName;
locationObj.addressComponents = gmapContext.addressComponents;
return {
map: gmapContext.map,
marker: gmapContext.marker,
location: locationObj
};
} else {
return null;
}
case "autosize":
autosize(gmapContext);
return this;
} }
return null; return null;
} }
return this.each(function() { return this.each(function() {
var $target = $(this); var $target = $(this);
// If plug-in hasn't been applied before - initialize, otherwise - skip if (isPluginApplied(this)) {
if (isPluginApplied(this)) return; updateMap(getContextForElement(this), $(this), options);
// Plug-in initialization is required return;
// Defaults }
var settings = $.extend({}, $.fn.locationpicker.defaults, options ); var settings = $.extend({}, $.fn.locationpicker.defaults, options);
// Initialize var gmapContext = new GMapContext(this, $.extend({}, {
var gmapContext = new GMapContext(this, {
zoom: settings.zoom, zoom: settings.zoom,
center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude), center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeId: settings.mapTypeId,
mapTypeControl: false, mapTypeControl: false,
styles: settings.styles,
disableDoubleClickZoom: false, disableDoubleClickZoom: false,
scrollwheel: settings.scrollwheel, scrollwheel: settings.scrollwheel,
streetViewControl: false, streetViewControl: false,
radius: settings.radius, radius: settings.radius,
locationName: settings.locationName, locationName: settings.locationName,
settings: settings settings: settings,
}); autocompleteOptions: settings.autocompleteOptions,
addressFormat: settings.addressFormat,
draggable: settings.draggable,
markerIcon: settings.markerIcon,
markerDraggable: settings.markerDraggable,
markerVisible: settings.markerVisible
}, settings.mapOptions));
$target.data("locationpicker", gmapContext); $target.data("locationpicker", gmapContext);
// Subscribe GMap events function displayMarkerWithSelectedArea() {
google.maps.event.addListener(gmapContext.marker, "dragend", function(event) { GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context) {
GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context){
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location); var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
context.settings.onchanged(currentLocation, context.radius, true); updateInputValues(gmapContext.settings.inputBinding, gmapContext);
context.settings.onchanged.apply(gmapContext.domContainer, [ currentLocation, context.radius, true ]);
});
}
if (settings.markerInCenter) {
gmapContext.map.addListener("bounds_changed", function() {
if (!gmapContext.marker.dragging) {
gmapContext.marker.setPosition(gmapContext.map.center);
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
}
});
gmapContext.map.addListener("idle", function() {
if (!gmapContext.marker.dragging) {
displayMarkerWithSelectedArea();
}
});
}
google.maps.event.addListener(gmapContext.marker, "drag", function(event) {
updateInputValues(gmapContext.settings.inputBinding, gmapContext); updateInputValues(gmapContext.settings.inputBinding, gmapContext);
}); });
google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
displayMarkerWithSelectedArea();
}); });
GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context){ GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context) {
updateInputValues(settings.inputBinding, gmapContext); updateInputValues(settings.inputBinding, gmapContext);
setupInputListenersInput(settings.inputBinding, gmapContext);
context.settings.oninitialized($target); context.settings.oninitialized($target);
}); });
// Set up input bindings if needed
setupInputListenersInput(settings.inputBinding, gmapContext);
}); });
}; };
$.fn.locationpicker.defaults = { $.fn.locationpicker.defaults = {
location: {latitude: 40.7324319, longitude: -73.82480799999996}, location: {
latitude: 40.7324319,
longitude: -73.82480777777776
},
locationName: "", locationName: "",
radius: 500, radius: 500,
zoom: 15, zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: [],
mapOptions: {},
scrollwheel: true, scrollwheel: true,
inputBinding: { inputBinding: {
latitudeInput: null, latitudeInput: null,
@@ -286,11 +385,16 @@
locationNameInput: null locationNameInput: null
}, },
enableAutocomplete: false, enableAutocomplete: false,
enableAutocompleteBlur: false,
autocompleteOptions: null,
addressFormat: "postal_code",
enableReverseGeocode: true, enableReverseGeocode: true,
draggable: true,
onchanged: function(currentLocation, radius, isMarkerDropped) {}, onchanged: function(currentLocation, radius, isMarkerDropped) {},
onlocationnotfound: function(locationName) {}, onlocationnotfound: function(locationName) {},
oninitialized: function (component) {} oninitialized: function(component) {},
markerIcon: undefined,
} markerDraggable: true,
markerVisible: true
}( jQuery )); };
})(jQuery);