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