|
1 /* Copyright 2009 the Melange authors. |
|
2 * |
|
3 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
4 * you may not use this file except in compliance with the License. |
|
5 * You may obtain a copy of the License at |
|
6 * |
|
7 * http://www.apache.org/licenses/LICENSE-2.0 |
|
8 * |
|
9 * Unless required by applicable law or agreed to in writing, software |
|
10 * distributed under the License is distributed on an "AS IS" BASIS, |
|
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
12 * See the License for the specific language governing permissions and |
|
13 * limitations under the License. |
|
14 */ |
|
15 /** |
|
16 * @author <a href="mailto:fadinlight@gmail.com">Mario Ferraro</a> |
|
17 */ |
|
18 |
|
19 (function () { |
|
20 var melange = window.melange; |
|
21 this.prototype = new melange.templates._baseTemplate(); |
|
22 this.prototype.constructor = melange.templates._baseTemplate; |
|
23 melange.templates._baseTemplate.apply(this, arguments); |
|
24 |
|
25 var _self = this; |
|
26 |
|
27 // Create global variables |
|
28 var map; |
|
29 var marker; |
|
30 var geocoder; |
|
31 |
|
32 // The following strings can be customized to reflect ids in the page. |
|
33 // You can also add or remove fields used for GMap Geocoding in |
|
34 // the JSON address object |
|
35 |
|
36 var current_lat = 0; |
|
37 var current_lng = 0; |
|
38 |
|
39 // Two different levels for zoom: Starting one and an inner that |
|
40 // is used when showing the map if lat and lon page fields are set |
|
41 var world_zoom = 0; |
|
42 var country_zoom = 4; |
|
43 var state_zoom = 6; |
|
44 var city_zoom = 10; |
|
45 var address_zoom = 13; |
|
46 |
|
47 // Do not add a starting # as this JQuery selector seems |
|
48 // incompatible with GMap API |
|
49 var map_div = "role_profile_map"; |
|
50 |
|
51 var field_lat = "#id_latitude"; |
|
52 var field_lng = "#id_longitude"; |
|
53 // Need to save old values to avoid unwanted updating |
|
54 // of lat and lot if marker dragged and blur another time an address field |
|
55 var address = { |
|
56 street: { |
|
57 id: "#id_res_street", |
|
58 old_value: "" |
|
59 }, |
|
60 city: { |
|
61 id: "#id_res_city", |
|
62 old_value: "" |
|
63 }, |
|
64 state: { |
|
65 id: "#id_res_state", |
|
66 old_value: "" |
|
67 }, |
|
68 country: { |
|
69 id: "#id_res_country", |
|
70 old_value: "" |
|
71 }, |
|
72 postalcode: { |
|
73 id: "#id_res_postalcode", |
|
74 old_value: "" |
|
75 } |
|
76 }; |
|
77 |
|
78 // Save current address fields in the JSON Object |
|
79 function saveOldAddress() { |
|
80 jQuery.each(address, function (level, level_details) { |
|
81 level_details.old_value = jQuery(level_details.id).val(); |
|
82 }); |
|
83 } |
|
84 |
|
85 // Return true if the user has edited address fields |
|
86 function isNewAddress() { |
|
87 var is_new = false; |
|
88 jQuery.each(address, function (level, level_details) { |
|
89 if (jQuery(level_details.id).val() !== level_details.old_value) { |
|
90 is_new = true; |
|
91 return false; |
|
92 } |
|
93 }); |
|
94 return is_new; |
|
95 } |
|
96 |
|
97 // Write saved lat and lng values to page fields |
|
98 function setLatLngFields() { |
|
99 jQuery(field_lat).val(current_lat); |
|
100 jQuery(field_lng).val(current_lng); |
|
101 } |
|
102 |
|
103 // Read lat and lng fields and store them |
|
104 function readLatLngFields() { |
|
105 current_lat = jQuery(field_lat).val(); |
|
106 current_lng = jQuery(field_lng).val(); |
|
107 } |
|
108 |
|
109 // This function reads address fields, merge them and uses |
|
110 // GMap API geocoding to find the first hit |
|
111 // Using geocoding |
|
112 // http://code.google.com/intl/it-IT/apis/maps/documentation/ |
|
113 // services.html#Geocoding |
|
114 function calculateAddress() { |
|
115 // If the user has really edited address fields... |
|
116 if (isNewAddress()) { |
|
117 // Merge address fields |
|
118 var address_string = ""; |
|
119 jQuery.each(address, function (level, level_details) { |
|
120 address_string += jQuery(level_details.id).val() + ","; |
|
121 }); |
|
122 |
|
123 // Ask GMap API for geocoding |
|
124 geocoder.getLatLng( |
|
125 address_string, |
|
126 function (point) { |
|
127 // If a point is found |
|
128 if (point) { |
|
129 // Save the current address in the JSON object |
|
130 saveOldAddress(); |
|
131 // Set the new zoom, map center and marker coords |
|
132 var zoom_set = world_zoom; |
|
133 if (jQuery(address.street.id).val() !== "") { |
|
134 zoom_set = address_zoom; |
|
135 } |
|
136 else if (jQuery(address.city.id).val() !== "") { |
|
137 zoom_set = city_zoom; |
|
138 } |
|
139 else if (jQuery(address.state.id).val() !== "") { |
|
140 zoom_set = state_zoom; |
|
141 } |
|
142 else if (jQuery(address.country.id).val() !== "") { |
|
143 zoom_set = country_zoom; |
|
144 } |
|
145 map.setCenter(point, zoom_set); |
|
146 marker.setPoint(point); |
|
147 map.clearOverlays(); |
|
148 map.addOverlay(marker); |
|
149 // Save point coords in local variables and then update |
|
150 // the page lat/lng fields |
|
151 current_lat = point.lat(); |
|
152 current_lng = point.lng(); |
|
153 setLatLngFields(); |
|
154 } |
|
155 } |
|
156 ); |
|
157 } |
|
158 } |
|
159 |
|
160 // Public function to load the map |
|
161 function map_load() { |
|
162 // All can happen only if there is gmap compatible browser. |
|
163 // TODO: Fallback in case the browser is not compatible |
|
164 if (google.maps.BrowserIsCompatible()) { |
|
165 // Save the address fields. This is useful if the page is being edited |
|
166 // to not update blindly the lat/lng fields with GMap geocoding if |
|
167 // blurring an address field |
|
168 saveOldAddress(); |
|
169 var starting_point; |
|
170 var zoom_selected = world_zoom; |
|
171 var show_marker = true; |
|
172 |
|
173 // Create the map and add small controls |
|
174 map = new google.maps.Map2(document.getElementById(map_div)); |
|
175 map.addControl(new google.maps.SmallMapControl()); |
|
176 map.addControl(new google.maps.MapTypeControl()); |
|
177 |
|
178 // Instantiate a global geocoder for future use |
|
179 geocoder = new google.maps.ClientGeocoder(); |
|
180 |
|
181 // If lat and lng fields are not void (the page is being edited) then |
|
182 // update the starting coords, modify the zoom level and tells following |
|
183 // code to show the marker |
|
184 if (jQuery(field_lat).val() !== "" && jQuery(field_lng).val() !== "") { |
|
185 readLatLngFields(); |
|
186 zoom_selected = address_zoom; |
|
187 show_marker = true; |
|
188 } |
|
189 |
|
190 // Set map center, marker coords and show it if this is an editing |
|
191 starting_point = new google.maps.LatLng(current_lat, current_lng); |
|
192 map.setCenter(starting_point, zoom_selected); |
|
193 marker = new google.maps.Marker(starting_point, {draggable: true}); |
|
194 if (show_marker) { |
|
195 map.addOverlay(marker); |
|
196 } |
|
197 |
|
198 // Adds a new event listener to geocode the address when an address |
|
199 // field is blurred |
|
200 jQuery.each(address, function (level, level_details) { |
|
201 jQuery(level_details.id).blur(calculateAddress); |
|
202 }); |
|
203 |
|
204 // Adds a new event listener: if the marker has been dragged around... |
|
205 google.maps.Event.addListener(marker, "dragend", function () { |
|
206 // Update internal variables with current marker coords... |
|
207 current_lat = marker.getPoint().lat(); |
|
208 current_lng = marker.getPoint().lng(); |
|
209 // ...and set page fields accordingly |
|
210 setLatLngFields(); |
|
211 }); |
|
212 } |
|
213 } |
|
214 |
|
215 jQuery( |
|
216 function () { |
|
217 melange.loadGoogleApi("maps", "2", {}, map_load); |
|
218 } |
|
219 ); |
|
220 |
|
221 }()); |