Skip to content

Commit 147fe27

Browse files
author
Dmitry Berezovsky
committed
Initial commit
1 parent c02347e commit 147fe27

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,15 @@ jquery-locationpicker-plugin
22
============================
33

44
JQuery Location Picker plugin
5+
6+
This plug-in allows to easily find and select location on the Google map. Except of single point it allows to choose some area by providing center of the area and some radius. All the date can be saved to any html input element automatically as well as processed with javascript (callback support).
7+
8+
The other feature of the plug-in is automatical address resoulver wich allows to get address line from the selected latitude and longitude. Also plug-in supports search by address typed into the binded input element which uses autocomplete feature from Google API to make search process easier. In this case marker will be automatically positioned on the map after successull address resolution.
9+
10+
Currently plug-in uses JQuery and Google Maps. Integration is pretty simple:
11+
12+
```
13+
$('mycontainer').locationpicker();
14+
```
15+
16+

locationpicker.jquery.js

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
(function ( $ ) {
2+
3+
/**
4+
* Holds google map object and related utility entities.
5+
* @constructor
6+
*/
7+
function GMapContext(domElement, options) {
8+
var _map = new google.maps.Map(domElement, options);
9+
var _marker = new google.maps.Marker({
10+
position: new google.maps.LatLng(54.19335, -3.92695),
11+
map: _map,
12+
title: "Drag Me",
13+
draggable: true
14+
});
15+
return {
16+
map: _map,
17+
marker: _marker,
18+
circle: null,
19+
location: _marker.position,
20+
radius: options.radius,
21+
locationName: options.locationName,
22+
settings: options.settings,
23+
domContainer: domElement,
24+
geodecoder: new google.maps.Geocoder()
25+
}
26+
}
27+
28+
// Utility functions for Google Map Manipulations
29+
var GmUtility = {
30+
/**
31+
* Draw a circle over the the map. Returns circle object.
32+
* Also writes new circle object in gmapContext.
33+
*
34+
* @param center - LatLng of the center of the circle
35+
* @param radius - radius in meters
36+
* @param gmapContext - context
37+
* @param options
38+
*/
39+
drawCircle: function(gmapContext, center, radius, options) {
40+
if (gmapContext.circle != null) {
41+
gmapContext.circle.setMap(null);
42+
}
43+
if (radius > 0) {
44+
radius *= 1;
45+
options = $.extend({
46+
strokeColor: "#0000FF",
47+
strokeOpacity: 0.35,
48+
strokeWeight: 2,
49+
fillColor: "#0000FF",
50+
fillOpacity: 0.20
51+
}, options);
52+
options.map = gmapContext.map;
53+
options.radius = radius;
54+
options.center = center;
55+
gmapContext.circle = new google.maps.Circle(options);
56+
return gmapContext.circle;
57+
}
58+
return null;
59+
},
60+
/**
61+
*
62+
* @param gMapContext
63+
* @param location
64+
* @param callback
65+
*/
66+
setPosition: function(gMapContext, location, callback) {
67+
gMapContext.location = location;
68+
gMapContext.marker.setPosition(location);
69+
gMapContext.map.panTo(location);
70+
this.drawCircle(gMapContext, location, gMapContext.radius, {});
71+
if (gMapContext.settings.enableReverseGeocode) {
72+
gMapContext.geodecoder.geocode({latLng: gMapContext.location}, function(results, status){
73+
if (status == google.maps.GeocoderStatus.OK && results.length > 0){
74+
gMapContext.locationName = results[0].formatted_address;
75+
}
76+
if (callback) {
77+
callback.call(this, gMapContext);
78+
}
79+
});
80+
} else {
81+
if (callback) {
82+
callback.call(this, gmapContext);
83+
}
84+
}
85+
86+
},
87+
locationFromLatLng: function(lnlg) {
88+
return {latitude: lnlg.lat(), longitude: lnlg.lng()}
89+
}
90+
}
91+
92+
function isPluginApplied(domObj) {
93+
return getContextForElement(domObj) != undefined;
94+
}
95+
96+
function getContextForElement(domObj) {
97+
return $(domObj).data("locationpicker");
98+
}
99+
100+
function updateInputValues(inputBinding, gmapContext){
101+
if (!inputBinding) return;
102+
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
103+
if (inputBinding.latitudeInput) {
104+
inputBinding.latitudeInput.val(currentLocation.latitude);
105+
}
106+
if (inputBinding.longitudeInput) {
107+
inputBinding.longitudeInput.val(currentLocation.longitude);
108+
}
109+
if (inputBinding.radiusInput) {
110+
inputBinding.radiusInput.val(gmapContext.radius);
111+
}
112+
if (inputBinding.locationNameInput) {
113+
inputBinding.locationNameInput.val(gmapContext.locationName);
114+
}
115+
}
116+
117+
function setupInputListenersInput(inputBinding, gmapContext) {
118+
if (inputBinding) {
119+
inputBinding.radiusInput.on("change", function() {
120+
gmapContext.radius = $(this).val();
121+
GmUtility.setPosition(gmapContext, gmapContext.location);
122+
});
123+
if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
124+
gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0));
125+
google.maps.event.addListener(gmapContext.autocomplete, 'place_changed', function() {
126+
var place = gmapContext.autocomplete.getPlace();
127+
if (!place.geometry) {
128+
gmapContext.onlocationnotfound();
129+
return;
130+
}
131+
GmUtility.setPosition(gmapContext, place.geometry.location, function() {
132+
updateInputValues(inputBinding, gmapContext);
133+
});
134+
});
135+
}
136+
}
137+
}
138+
139+
/**
140+
* Initialization:
141+
* $("#myMap").locationpicker(options);
142+
* @param options
143+
* @param params
144+
* @returns {*}
145+
*/
146+
$.fn.locationpicker = function( options, params ) {
147+
if (typeof options == 'string') { // Command provided
148+
var _targetDomElement = this.get(0);
149+
// Plug-in is not applied - nothing to do.
150+
if (!isPluginApplied(_targetDomElement)) return;
151+
var gmapContext = getContextForElement(_targetDomElement);
152+
switch (options) {
153+
case "location":
154+
if (params == undefined) { // Getter
155+
var location = GmUtility.locationFromLatLng(gmapContext.location);
156+
location.radius = gmapContext.radius;
157+
location.name = gmapContext.locationName;
158+
return location;
159+
} else { // Setter
160+
if (params.radius) {
161+
gmapContext.radius = params.radius;
162+
}
163+
GmUtility.setPosition(gmapContext, new google.maps.LatLng(params.latitude, params.longitude), function(gmapContext) {
164+
updateInputValues(gmapContext.settings.inputBinding, gmapContext);
165+
});
166+
}
167+
break;
168+
case "subscribe":
169+
/**
170+
* Provides interface for subscribing for GoogleMap events.
171+
* See Google API documentation for details.
172+
* Parameters:
173+
* - event: string, name of the event
174+
* - callback: function, callback function to be invoked
175+
*/
176+
if (options == undefined) { // Getter is not available
177+
return null;
178+
} else {
179+
var event = params.event;
180+
var callback = params.callback;
181+
if (!event || ! callback) {
182+
console.error("LocationPicker: Invalid arguments for method \"subscribe\"")
183+
return null;
184+
}
185+
google.maps.event.addListener(gmapContext.map, event, callback);
186+
}
187+
188+
break;
189+
}
190+
return null;
191+
}
192+
return this.each(function() {
193+
var $target = $(this);
194+
// If plug-in hasn't been applied before - initialize, otherwise - skip
195+
if (isPluginApplied(this)) return;
196+
// Plug-in initialization is required
197+
// Defaults
198+
var settings = $.extend($.fn.locationpicker.defaults, options );
199+
// Initialize
200+
var gmapContext = new GMapContext(this, {
201+
zoom: settings.zoom,
202+
center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
203+
mapTypeId: google.maps.MapTypeId.ROADMAP,
204+
mapTypeControl: false,
205+
disableDoubleClickZoom: false,
206+
scrollwheel: settings.scrollwheel,
207+
streetViewControl: false,
208+
radius: settings.radius,
209+
locationName: settings.locationName,
210+
settings: settings
211+
});
212+
$(this).data("locationpicker", gmapContext);
213+
// Subscribe GMap events
214+
google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
215+
GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(){
216+
var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
217+
settings.onchanged(currentLocation, gmapContext.radius, true);
218+
updateInputValues(settings.inputBinding, gmapContext);
219+
});
220+
});
221+
GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(){
222+
updateInputValues(settings.inputBinding, gmapContext);
223+
settings.oninitialized($target);
224+
});
225+
// Set up input bindings if needed
226+
setupInputListenersInput(settings.inputBinding, gmapContext);
227+
});
228+
};
229+
$.fn.locationpicker.defaults = {
230+
location: {latitude: 40.7324319, longitude: -73.82480799999996},
231+
locationName: "",
232+
radius: 500,
233+
zoom: 15,
234+
scrollwheel: true,
235+
inputBinding: {
236+
latitudeInput: null,
237+
longitudeInput: null,
238+
radiusInput: null,
239+
locationNameInput: null
240+
},
241+
enableAutocomplete: false,
242+
enableReverseGeocode: true,
243+
onchanged: function(currentLocation, radius, isMarkerDropped) {},
244+
onlocationnotfound: function(locationName) {},
245+
oninitialized: function (component) {}
246+
247+
}
248+
249+
}( jQuery ));

0 commit comments

Comments
 (0)