PluginProbe
CBX Map for Google Map & OpenStreetMap / 1.1.11
CBX Map for Google Map & OpenStreetMap v1.1.11
trunk 1.1.10 1.1.11 1.1.12 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5
cbxgooglemap / assets / js / locationpicker.jquery.js

locationpicker.jquery.js in CBX Map for Google Map & OpenStreetMap 1.1.11, at assets/js/locationpicker.jquery.js

406 lines 19.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! jquery-locationpicker - v0.1.16 - 2017-10-02 */
2 (function($) {
3 function GMapContext(domElement, options) {
4 var _map = new google.maps.Map(domElement, options);
5 var _marker = new google.maps.Marker({
6 position: new google.maps.LatLng(54.19335, -3.92695),
7 map: _map,
8 title: "Drag Me",
9 visible: options.markerVisible,
10 draggable: options.markerDraggable,
11 icon: options.markerIcon !== undefined ? options.markerIcon : undefined
12 });
13 return {
14 map: _map,
15 marker: _marker,
16 circle: null,
17 location: _marker.position,
18 radius: options.radius,
19 locationName: options.locationName,
20 addressComponents: {
21 formatted_address: null,
22 addressLine1: null,
23 addressLine2: null,
24 streetName: null,
25 streetNumber: null,
26 city: null,
27 district: null,
28 state: null,
29 stateOrProvince: null
30 },
31 settings: options.settings,
32 domContainer: domElement,
33 geodecoder: new google.maps.Geocoder()
34 };
35 }
36 var GmUtility = {
37 drawCircle: function(gmapContext, center, radius, options) {
38 if (gmapContext.circle != null) {
39 gmapContext.circle.setMap(null);
40 }
41 if (radius > 0) {
42 radius *= 1;
43 options = $.extend({
44 strokeColor: "#0000FF",
45 strokeOpacity: .35,
46 strokeWeight: 2,
47 fillColor: "#0000FF",
48 fillOpacity: .2
49 }, options);
50 options.map = gmapContext.map;
51 options.radius = radius;
52 options.center = center;
53 gmapContext.circle = new google.maps.Circle(options);
54 return gmapContext.circle;
55 }
56 return null;
57 },
58 setPosition: function(gMapContext, location, callback) {
59 gMapContext.location = location;
60 gMapContext.marker.setPosition(location);
61 gMapContext.map.panTo(location);
62 this.drawCircle(gMapContext, location, gMapContext.radius, {});
63 if (gMapContext.settings.enableReverseGeocode) {
64 this.updateLocationName(gMapContext, callback);
65 } else {
66 if (callback) {
67 callback.call(this, gMapContext);
68 }
69 }
70 },
71 locationFromLatLng: function(lnlg) {
72 return {
73 latitude: lnlg.lat(),
74 longitude: lnlg.lng()
75 };
76 },
77 addressByFormat: function(addresses, format) {
78 var result = null;
79 for (var i = addresses.length - 1; i >= 0; i--) {
80 if (addresses[i].types.indexOf(format) >= 0) {
81 result = addresses[i];
82 }
83 }
84 return result || addresses[0];
85 },
86 updateLocationName: function(gmapContext, callback) {
87 gmapContext.geodecoder.geocode({
88 latLng: gmapContext.marker.position
89 }, function(results, status) {
90 if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
91 var address = GmUtility.addressByFormat(results, gmapContext.settings.addressFormat);
92 gmapContext.locationName = address.formatted_address;
93 gmapContext.addressComponents = GmUtility.address_component_from_google_geocode(address.address_components);
94 } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
95 return setTimeout(function() {
96 GmUtility.updateLocationName(gmapContext, callback);
97 }, 1e3);
98 }
99 if (callback) {
100 callback.call(this, gmapContext);
101 }
102 });
103 },
104 address_component_from_google_geocode: function(address_components) {
105 var result = {};
106 for (var i = address_components.length - 1; i >= 0; i--) {
107 var component = address_components[i];
108 if (component.types.indexOf("postal_code") >= 0) {
109 result.postalCode = component.short_name;
110 } else if (component.types.indexOf("street_number") >= 0) {
111 result.streetNumber = component.short_name;
112 } else if (component.types.indexOf("route") >= 0) {
113 result.streetName = component.short_name;
114 } else if (component.types.indexOf("locality") >= 0) {
115 result.city = component.short_name;
116 } else if (component.types.indexOf("sublocality") >= 0) {
117 result.district = component.short_name;
118 } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
119 result.stateOrProvince = component.short_name;
120 } else if (component.types.indexOf("country") >= 0) {
121 result.country = component.short_name;
122 }
123 }
124 result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
125 result.addressLine2 = "";
126 return result;
127 }
128 };
129 function isPluginApplied(domObj) {
130 return getContextForElement(domObj) != undefined;
131 }
132 function getContextForElement(domObj) {
133 return $(domObj).data("locationpicker");
134 }
135 function updateInputValues(inputBinding, gmapContext) {
136 if (!inputBinding) return;
137 var currentLocation = GmUtility.locationFromLatLng(gmapContext.marker.position);
138 if (inputBinding.latitudeInput) {
139 inputBinding.latitudeInput.val(currentLocation.latitude).change();
140 }
141 if (inputBinding.longitudeInput) {
142 inputBinding.longitudeInput.val(currentLocation.longitude).change();
143 }
144 if (inputBinding.radiusInput) {
145 inputBinding.radiusInput.val(gmapContext.radius).change();
146 }
147 if (inputBinding.locationNameInput) {
148 inputBinding.locationNameInput.val(gmapContext.locationName).change();
149 }
150
151 if (inputBinding.zoomInput) {
152 inputBinding.zoomInput.val(gmapContext.map.getZoom()).change();
153 }
154 }
155 function setupInputListenersInput(inputBinding, gmapContext) {
156 if (inputBinding) {
157 if (inputBinding.radiusInput) {
158 inputBinding.radiusInput.on("change", function(e) {
159 var radiusInputValue = $(this).val();
160 if (!e.originalEvent || isNaN(radiusInputValue)) {
161 return;
162 }
163 gmapContext.radius = radiusInputValue;
164 GmUtility.setPosition(gmapContext, gmapContext.location, function(context) {
165 context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
166 });
167 });
168 }
169 if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
170 var blur = false;
171 gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0), gmapContext.settings.autocompleteOptions);
172 google.maps.event.addListener(gmapContext.autocomplete, "place_changed", function() {
173 blur = false;
174 var place = gmapContext.autocomplete.getPlace();
175 if (!place.geometry) {
176 gmapContext.settings.onlocationnotfound(place.name);
177 return;
178 }
179 GmUtility.setPosition(gmapContext, place.geometry.location, function(context) {
180 updateInputValues(inputBinding, context);
181 context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
182 });
183 });
184 if (gmapContext.settings.enableAutocompleteBlur) {
185 inputBinding.locationNameInput.on("change", function(e) {
186 if (!e.originalEvent) {
187 return;
188 }
189 blur = true;
190 });
191 inputBinding.locationNameInput.on("blur", function(e) {
192 if (!e.originalEvent) {
193 return;
194 }
195 setTimeout(function() {
196 var address = $(inputBinding.locationNameInput).val();
197 if (address.length > 5 && blur) {
198 blur = false;
199 gmapContext.geodecoder.geocode({
200 address: address
201 }, function(results, status) {
202 if (status == google.maps.GeocoderStatus.OK && results && results.length) {
203 GmUtility.setPosition(gmapContext, results[0].geometry.location, function(context) {
204 updateInputValues(inputBinding, context);
205 context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
206 });
207 }
208 });
209 }
210 }, 1e3);
211 });
212 }
213 }
214 if (inputBinding.latitudeInput) {
215 inputBinding.latitudeInput.on("change", function(e) {
216 var latitudeInputValue = $(this).val();
217 if (!e.originalEvent || isNaN(latitudeInputValue)) {
218 return;
219 }
220 GmUtility.setPosition(gmapContext, new google.maps.LatLng(latitudeInputValue, gmapContext.location.lng()), function(context) {
221 context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
222 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
223 });
224 });
225 }
226 if (inputBinding.longitudeInput) {
227 inputBinding.longitudeInput.on("change", function(e) {
228 var longitudeInputValue = $(this).val();
229 if (!e.originalEvent || isNaN(longitudeInputValue)) {
230 return;
231 }
232 GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), longitudeInputValue), function(context) {
233 context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
234 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
235 });
236 });
237 }
238 }
239 }
240 function autosize(gmapContext) {
241 google.maps.event.trigger(gmapContext.map, "resize");
242 setTimeout(function() {
243 gmapContext.map.setCenter(gmapContext.marker.position);
244 }, 300);
245 }
246 function updateMap(gmapContext, $target, options) {
247 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;
248 if (latNew == latOld && lngNew == lngOld && radiusNew == radiusOld) return;
249 gmapContext.settings.location.latitude = latNew;
250 gmapContext.settings.location.longitude = lngNew;
251 gmapContext.radius = radiusNew;
252 GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.settings.location.latitude, gmapContext.settings.location.longitude), function(context) {
253 setupInputListenersInput(gmapContext.settings.inputBinding, gmapContext);
254 context.settings.oninitialized($target);
255 });
256 }
257 $.fn.locationpicker = function(options, params) {
258 if (typeof options == "string") {
259 var _targetDomElement = this.get(0);
260 if (!isPluginApplied(_targetDomElement)) return;
261 var gmapContext = getContextForElement(_targetDomElement);
262 switch (options) {
263 case "location":
264 if (params == undefined) {
265 var location = GmUtility.locationFromLatLng(gmapContext.location);
266 location.radius = gmapContext.radius;
267 location.name = gmapContext.locationName;
268 return location;
269 } else {
270 if (params.radius) {
271 gmapContext.radius = params.radius;
272 }
273 GmUtility.setPosition(gmapContext, new google.maps.LatLng(params.latitude, params.longitude), function(gmapContext) {
274 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
275 });
276 }
277 break;
278
279 case "subscribe":
280 if (params == undefined) {
281 return null;
282 } else {
283 var event = params.event;
284 var callback = params.callback;
285 if (!event || !callback) {
286 console.error('LocationPicker: Invalid arguments for method "subscribe"');
287 return null;
288 }
289 google.maps.event.addListener(gmapContext.map, event, callback);
290 }
291 break;
292
293 case "map":
294 if (params == undefined) {
295 var locationObj = GmUtility.locationFromLatLng(gmapContext.location);
296 locationObj.formattedAddress = gmapContext.locationName;
297 locationObj.addressComponents = gmapContext.addressComponents;
298 return {
299 map: gmapContext.map,
300 marker: gmapContext.marker,
301 location: locationObj
302 };
303 } else {
304 return null;
305 }
306
307 case "autosize":
308 autosize(gmapContext);
309 return this;
310 }
311 return null;
312 }
313 return this.each(function() {
314 var $target = $(this);
315 if (isPluginApplied(this)) {
316 updateMap(getContextForElement(this), $(this), options);
317 return;
318 }
319 var settings = $.extend({}, $.fn.locationpicker.defaults, options);
320 var gmapContext = new GMapContext(this, $.extend({}, {
321 zoom: settings.zoom,
322 center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
323 mapTypeId: settings.mapTypeId,
324 mapTypeControl: false,
325 styles: settings.styles,
326 disableDoubleClickZoom: false,
327 scrollwheel: settings.scrollwheel,
328 streetViewControl: false,
329 radius: settings.radius,
330 locationName: settings.locationName,
331 settings: settings,
332 autocompleteOptions: settings.autocompleteOptions,
333 addressFormat: settings.addressFormat,
334 draggable: settings.draggable,
335 markerIcon: settings.markerIcon,
336 markerDraggable: settings.markerDraggable,
337 markerVisible: settings.markerVisible
338 }, settings.mapOptions));
339 $target.data("locationpicker", gmapContext);
340 function displayMarkerWithSelectedArea() {
341 GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context) {
342 var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
343 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
344 context.settings.onchanged.apply(gmapContext.domContainer, [ currentLocation, context.radius, true ]);
345 });
346 }
347 if (settings.markerInCenter) {
348 gmapContext.map.addListener("bounds_changed", function() {
349 if (!gmapContext.marker.dragging) {
350 gmapContext.marker.setPosition(gmapContext.map.center);
351 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
352 }
353 });
354 //gmapContext.map.addListener("idle", function() {
355 gmapContext.map.addListener("dragend", function() {
356 if (!gmapContext.marker.dragging) {
357 displayMarkerWithSelectedArea();
358 }
359 });
360 }
361 google.maps.event.addListener(gmapContext.marker, "drag", function(event) {
362 updateInputValues(gmapContext.settings.inputBinding, gmapContext);
363 });
364 google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
365 displayMarkerWithSelectedArea();
366 });
367 GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context) {
368 updateInputValues(settings.inputBinding, gmapContext);
369 setupInputListenersInput(settings.inputBinding, gmapContext);
370 context.settings.oninitialized($target);
371 });
372 });
373 };
374 $.fn.locationpicker.defaults = {
375 location: {
376 latitude: 40.7324319,
377 longitude: -73.82480777777776
378 },
379 locationName: "",
380 radius: 500,
381 zoom: 15,
382 mapTypeId: google.maps.MapTypeId.ROADMAP,
383 styles: [],
384 mapOptions: {},
385 scrollwheel: true,
386 inputBinding: {
387 latitudeInput: null,
388 longitudeInput: null,
389 radiusInput: null,
390 locationNameInput: null,
391 zoomInput:null
392 },
393 enableAutocomplete: false,
394 enableAutocompleteBlur: false,
395 autocompleteOptions: null,
396 addressFormat: "postal_code",
397 enableReverseGeocode: true,
398 draggable: true,
399 onchanged: function(currentLocation, radius, isMarkerDropped) {},
400 onlocationnotfound: function(locationName) {},
401 oninitialized: function(component) {},
402 markerIcon: undefined,
403 markerDraggable: true,
404 markerVisible: true
405 };
406 })(jQuery);