1 |
|
---|
2 |
|
---|
3 | scheduler.xy.map_date_width = 188; // date column width
|
---|
4 | scheduler.xy.map_description_width = 400; // description column width
|
---|
5 |
|
---|
6 | scheduler.config.map_resolve_event_location = true; // if events in database doesn't have lat and lng values there will be an attempt to resolve them on event loading, useful for migration
|
---|
7 | scheduler.config.map_resolve_user_location = true; // if user will be promted to share his location to display it on the map
|
---|
8 |
|
---|
9 | scheduler.config.map_initial_position = new google.maps.LatLng(48.724, 8.215); // inital position of the map
|
---|
10 | scheduler.config.map_error_position = new google.maps.LatLng(15, 15); // this position will be displayed in case if event doesn't have corresponding coordinates
|
---|
11 |
|
---|
12 | scheduler.config.map_infowindow_max_width = 300;
|
---|
13 |
|
---|
14 | scheduler.config.map_type = google.maps.MapTypeId.ROADMAP;
|
---|
15 |
|
---|
16 | scheduler.config.map_zoom_after_resolve = 15;
|
---|
17 |
|
---|
18 | scheduler.locale.labels.marker_geo_success = "It seems you are here.";
|
---|
19 | scheduler.locale.labels.marker_geo_fail = "Sorry, could not get your current position using geolocation.";
|
---|
20 |
|
---|
21 | scheduler.templates.marker_date=scheduler.date.date_to_str("%Y-%m-%d %H:%i"); // date for map's infowindow will be formated following way
|
---|
22 |
|
---|
23 | scheduler.templates.marker_text=function(start, end, ev){
|
---|
24 | return "<div><b>"+ev.text+"</b><br/><br/>"+(ev.event_location||'')+"<br/><br/>"+scheduler.templates.marker_date(start)+" - "+scheduler.templates.marker_date(end)+"</div>";
|
---|
25 | };
|
---|
26 | scheduler.dblclick_dhx_map_area=function(){
|
---|
27 | if (!this.config.readonly && this.config.dblclick_create)
|
---|
28 | this.addEventNow();
|
---|
29 | };
|
---|
30 | scheduler.templates.map_time = function(start,end,ev){
|
---|
31 | if (ev._timed)
|
---|
32 | return this.day_date(ev.start_date, ev.end_date, ev)+" "+this.event_date(start);
|
---|
33 | else
|
---|
34 | return scheduler.templates.day_date(start)+" – "+scheduler.templates.day_date(end);
|
---|
35 | };
|
---|
36 | scheduler.templates.map_text = function(ev){
|
---|
37 | return ev.text;
|
---|
38 | };
|
---|
39 | scheduler.date.map_start=function(d){ return d; };
|
---|
40 |
|
---|
41 |
|
---|
42 | scheduler.attachEvent("onTemplatesReady",function(){
|
---|
43 |
|
---|
44 | function _append_map() {
|
---|
45 | _isPositionSet = false; // if user actual (geolocation) position was set on the map
|
---|
46 |
|
---|
47 | var gmap = document.createElement('div');
|
---|
48 | gmap.className='dhx_map';
|
---|
49 | gmap.id='dhx_gmap';
|
---|
50 | gmap.style.dispay = "none";
|
---|
51 |
|
---|
52 | node = document.getElementById('scheduler_here');
|
---|
53 |
|
---|
54 | node.appendChild(gmap);
|
---|
55 |
|
---|
56 | scheduler._els.dhx_gmap = [];
|
---|
57 | scheduler._els.dhx_gmap.push(gmap);
|
---|
58 |
|
---|
59 | _setMapSize('dhx_gmap');
|
---|
60 |
|
---|
61 | var mapOptions = {
|
---|
62 | zoom: scheduler.config.map_inital_zoom || 10,
|
---|
63 | center: scheduler.config.map_initial_position,
|
---|
64 | mapTypeId: scheduler.config.map_type||google.maps.MapTypeId.ROADMAP
|
---|
65 | };
|
---|
66 | map = new google.maps.Map(document.getElementById('dhx_gmap'), mapOptions);
|
---|
67 | map.disableDefaultUI = false;
|
---|
68 | map.disableDoubleClickZoom = true;
|
---|
69 |
|
---|
70 | google.maps.event.addListener(map, "dblclick", function(event) {
|
---|
71 | if (!scheduler.config.readonly && scheduler.config.dblclick_create) {
|
---|
72 | point = event.latLng;
|
---|
73 | geocoder.geocode(
|
---|
74 | { 'latLng': point },
|
---|
75 | function(results, status) {
|
---|
76 | if (status == google.maps.GeocoderStatus.OK) {
|
---|
77 | point = results[0].geometry.location;
|
---|
78 | scheduler.addEventNow({
|
---|
79 | lat: point.lat(),
|
---|
80 | lng: point.lng(),
|
---|
81 | event_location: results[0].formatted_address
|
---|
82 | });
|
---|
83 | }
|
---|
84 | }
|
---|
85 | );
|
---|
86 | }
|
---|
87 | });
|
---|
88 |
|
---|
89 | var infoWindowOptions = {
|
---|
90 | content: ''
|
---|
91 | };
|
---|
92 |
|
---|
93 | if (scheduler.config.map_infowindow_max_width) {
|
---|
94 | infoWindowOptions.maxWidth = scheduler.config.map_infowindow_max_width;
|
---|
95 | }
|
---|
96 |
|
---|
97 | scheduler.map = {
|
---|
98 | _points: [],
|
---|
99 | _markers: [],
|
---|
100 | _infowindow: new google.maps.InfoWindow(infoWindowOptions),
|
---|
101 | _infowindows_content: [],
|
---|
102 | _initialization_count: -1
|
---|
103 | };
|
---|
104 |
|
---|
105 | geocoder = new google.maps.Geocoder();
|
---|
106 |
|
---|
107 | if(scheduler.config.map_resolve_user_location) {
|
---|
108 | if(navigator.geolocation) {
|
---|
109 | if(!_isPositionSet) {
|
---|
110 | navigator.geolocation.getCurrentPosition(function(position) {
|
---|
111 | var _userLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
|
---|
112 | map.setCenter(_userLocation);
|
---|
113 | map.setZoom(scheduler.config.map_zoom_after_resolve||10);
|
---|
114 | scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_success);
|
---|
115 | scheduler.map._infowindow.position = map.getCenter();
|
---|
116 | scheduler.map._infowindow.open(map);
|
---|
117 |
|
---|
118 | _isPositionSet = true;
|
---|
119 | },
|
---|
120 | function() {
|
---|
121 | scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_fail);
|
---|
122 | scheduler.map._infowindow.setPosition(map.getCenter());
|
---|
123 | scheduler.map._infowindow.open(map);
|
---|
124 | _isPositionSet = true;
|
---|
125 | });
|
---|
126 | }
|
---|
127 | }
|
---|
128 | }
|
---|
129 | google.maps.event.addListener(map, "resize", function(event) {
|
---|
130 | gmap.style.zIndex='5';
|
---|
131 | map.setZoom( map.getZoom() );
|
---|
132 | });
|
---|
133 | google.maps.event.addListener(map, "tilesloaded", function(event) {
|
---|
134 | gmap.style.zIndex='5';
|
---|
135 | });
|
---|
136 | }
|
---|
137 | _append_map();
|
---|
138 |
|
---|
139 | scheduler.attachEvent("onSchedulerResize",function(){
|
---|
140 | if (this._mode == "map"){
|
---|
141 | this.map_view(true);
|
---|
142 | }
|
---|
143 | });
|
---|
144 |
|
---|
145 | var old = scheduler.render_data;
|
---|
146 | scheduler.render_data=function(evs,hold){
|
---|
147 | if (this._mode == "map") {
|
---|
148 | fill_map_tab();
|
---|
149 | var events = scheduler.get_visible_events();
|
---|
150 | for(var i=0; i<events.length; i++) {
|
---|
151 | if(!scheduler.map._markers[events[i].id]) {
|
---|
152 | showAddress(events[i],false,false);
|
---|
153 | }
|
---|
154 | }
|
---|
155 | } else
|
---|
156 | return old.apply(this,arguments);
|
---|
157 | };
|
---|
158 |
|
---|
159 | function set_full_view(mode){
|
---|
160 | if (mode){
|
---|
161 | var l = scheduler.locale.labels;
|
---|
162 | scheduler._els["dhx_cal_header"][0].innerHTML="<div class='dhx_map_line' style='width: "+(scheduler.xy.map_date_width+scheduler.xy.map_description_width+2)+"px;' ><div style='width: "+scheduler.xy.map_date_width+"px;'>"+l.date+"</div><div class='headline_description' style='width: "+scheduler.xy.map_description_width+"px;'>"+l.description+"</div></div>";
|
---|
163 | scheduler._table_view=true;
|
---|
164 | scheduler.set_sizes();
|
---|
165 | }
|
---|
166 | }
|
---|
167 |
|
---|
168 | function fill_map_tab(){
|
---|
169 | //get current date
|
---|
170 | var date = scheduler._date;
|
---|
171 | //select events for which data need to be printed
|
---|
172 | var events = scheduler.get_visible_events();
|
---|
173 | events.sort(function(a,b){ return a.start_date>b.start_date?1:-1; });
|
---|
174 |
|
---|
175 | //generate html for the view
|
---|
176 | var html="<div class='dhx_map_area'>";
|
---|
177 | for (var i=0; i<events.length; i++){
|
---|
178 | var event_class = (events[i].id == scheduler._selected_event_id)?'dhx_map_line highlight':'dhx_map_line';
|
---|
179 | html+="<div class='"+event_class+"' event_id='"+events[i].id+"' style='"+(events[i]._text_style||"")+" width: "+(scheduler.xy.map_date_width+scheduler.xy.map_description_width+2)+"px;'><div style='width: "+scheduler.xy.map_date_width+"px;' >"+scheduler.templates.map_time(events[i].start_date, events[i].end_date,events[i])+"</div>";
|
---|
180 | html+="<div class='dhx_event_icon icon_details'> </div>";
|
---|
181 | html+="<div class='line_description' style='width:"+(scheduler.xy.map_description_width-25)+"px;'>"+scheduler.templates.map_text(events[i])+"</div></div>"; // -25 = icon size 20 and padding 5
|
---|
182 | }
|
---|
183 | html+="<div class='dhx_v_border' style='left: "+(scheduler.xy.map_date_width-2)+"px;'></div><div class='dhx_v_border_description'></div></div>";
|
---|
184 |
|
---|
185 | //render html
|
---|
186 | scheduler._els["dhx_cal_data"][0].scrollTop = 0; //fix flickering in FF
|
---|
187 | scheduler._els["dhx_cal_data"][0].innerHTML = html;
|
---|
188 | scheduler._els["dhx_cal_data"][0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
---|
189 |
|
---|
190 | var t=scheduler._els["dhx_cal_data"][0].firstChild.childNodes;
|
---|
191 | scheduler._els["dhx_cal_date"][0].innerHTML="";
|
---|
192 |
|
---|
193 | scheduler._rendered=[];
|
---|
194 | for (var i=0; i < t.length-2; i++) {
|
---|
195 | scheduler._rendered[i]=t[i];
|
---|
196 | }
|
---|
197 |
|
---|
198 | }
|
---|
199 |
|
---|
200 | function _setMapSize(elem_id) { //input - map's div id
|
---|
201 | var map = document.getElementById(elem_id);
|
---|
202 | map.style.height = (scheduler._y - scheduler.xy.nav_height) + 'px';
|
---|
203 | map.style.width = (scheduler._x - scheduler.xy.map_date_width - scheduler.xy.map_description_width - 1) + 'px';
|
---|
204 | map.style.marginLeft = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
---|
205 | map.style.marginTop = (scheduler.xy.nav_height + 2) + 'px';
|
---|
206 | }
|
---|
207 |
|
---|
208 | scheduler.map_view=function(mode){
|
---|
209 | scheduler.map._initialization_count++;
|
---|
210 | var gmap = scheduler._els.dhx_gmap[0];
|
---|
211 |
|
---|
212 | scheduler._els.dhx_cal_data[0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
---|
213 |
|
---|
214 | scheduler._min_date = scheduler.config.map_start||(new Date());
|
---|
215 | scheduler._max_date = scheduler.config.map_end||(new Date(9999,1,1));
|
---|
216 | scheduler._table_view = true;
|
---|
217 | set_full_view(mode);
|
---|
218 |
|
---|
219 | if (mode){ //map tab activated
|
---|
220 | fill_map_tab();
|
---|
221 | gmap.style.display = 'block';
|
---|
222 |
|
---|
223 | // need to resize block everytime window is resized
|
---|
224 | _setMapSize('dhx_gmap');
|
---|
225 |
|
---|
226 | var events = scheduler.get_visible_events();
|
---|
227 | for(var i=0; i<events.length; i++) {
|
---|
228 | if(!scheduler.map._markers[events[i].id]) {
|
---|
229 | showAddress(events[i]);
|
---|
230 | }
|
---|
231 | }
|
---|
232 | } else { //map tab de-activated
|
---|
233 | gmap.style.display = 'none';
|
---|
234 | }
|
---|
235 |
|
---|
236 | google.maps.event.trigger(map, 'resize');
|
---|
237 | if(scheduler.map._initialization_count === 0) { // if tab is activated for the first time need to fix position
|
---|
238 | map.setCenter(scheduler.config.map_initial_position);
|
---|
239 | }
|
---|
240 | };
|
---|
241 |
|
---|
242 | function showAddress(event, setCenter, performClick) { // what if event have incorrect position from the start?
|
---|
243 | if(event.lat && event.lng) {
|
---|
244 | var point = new google.maps.LatLng(event.lat,event.lng);
|
---|
245 | } else {
|
---|
246 | var point = scheduler.config.map_error_position;
|
---|
247 | }
|
---|
248 | var message = scheduler.templates.marker_text(event.start_date, event.end_date, event);
|
---|
249 | if(!scheduler._new_event) {
|
---|
250 | scheduler.map._markers[event.id]= new google.maps.Marker({
|
---|
251 | position: point,
|
---|
252 | map: map
|
---|
253 | });
|
---|
254 |
|
---|
255 | scheduler.map._infowindows_content[event.id] = message;
|
---|
256 |
|
---|
257 | google.maps.event.addListener(scheduler.map._markers[event.id], 'click', function() {
|
---|
258 | scheduler.map._infowindow.setContent(scheduler.map._infowindows_content[event.id]);
|
---|
259 | scheduler.map._infowindow.open(map,scheduler.map._markers[event.id]);
|
---|
260 | scheduler._selected_event_id = event.id;
|
---|
261 | scheduler.render_data();
|
---|
262 | });
|
---|
263 |
|
---|
264 | scheduler.map._points[event.id]=point;
|
---|
265 |
|
---|
266 | if(setCenter) map.setCenter(scheduler.map._points[event.id]);
|
---|
267 | if(performClick) scheduler.callEvent("onClick", [event.id]);
|
---|
268 | }
|
---|
269 | }
|
---|
270 |
|
---|
271 | scheduler.attachEvent("onClick",function(event_id, native_event_object){
|
---|
272 | if (this._mode == "map"){
|
---|
273 | scheduler._selected_event_id = event_id;
|
---|
274 | for(var i=0; i<scheduler._rendered.length; i++) {
|
---|
275 | scheduler._rendered[i].className='dhx_map_line';
|
---|
276 | if(scheduler._rendered[i].getAttribute("event_id") == event_id) {
|
---|
277 | scheduler._rendered[i].className += " highlight";
|
---|
278 | }
|
---|
279 | }
|
---|
280 | if(scheduler.map._points[event_id] && scheduler.map._markers[event_id]) {
|
---|
281 | map.panTo(scheduler.map._points[event_id]);
|
---|
282 | google.maps.event.trigger(scheduler.map._markers[event_id], 'click');
|
---|
283 | }
|
---|
284 | }
|
---|
285 | return true;
|
---|
286 | });
|
---|
287 |
|
---|
288 | _displayEventOnMap = function(event) {
|
---|
289 | if (event.event_location && geocoder) {
|
---|
290 | geocoder.geocode(
|
---|
291 | { 'address': event.event_location },
|
---|
292 | function(results, status) {
|
---|
293 | var point = {};
|
---|
294 | if (status != google.maps.GeocoderStatus.OK) {
|
---|
295 | point = scheduler.callEvent("onLocationError",[event.id]);
|
---|
296 | if (!point || point === true)
|
---|
297 | point = scheduler.config.map_error_position;
|
---|
298 | } else {
|
---|
299 | point = results[0].geometry.location;
|
---|
300 | }
|
---|
301 | event.lat = point.lat();
|
---|
302 | event.lng = point.lng();
|
---|
303 |
|
---|
304 | scheduler._selected_event_id = event.id;
|
---|
305 |
|
---|
306 | showAddress(event, true, true);
|
---|
307 | dp.setUpdated(event.id, true, "updated");
|
---|
308 | }
|
---|
309 | );
|
---|
310 | } else {
|
---|
311 | showAddress(event, true, true);
|
---|
312 | }
|
---|
313 | };
|
---|
314 |
|
---|
315 | _updateEventLocation = function(event) { // update lat and lng in database
|
---|
316 | if (event.event_location && geocoder) {
|
---|
317 | geocoder.geocode(
|
---|
318 | { 'address': event.event_location },
|
---|
319 | function(results, status) {
|
---|
320 | var point = {};
|
---|
321 | if (status != google.maps.GeocoderStatus.OK) {
|
---|
322 | point = scheduler.callEvent("onLocationError",[event.id]);
|
---|
323 | if (!point || point === true)
|
---|
324 | point = scheduler.config.map_error_position;
|
---|
325 | } else {
|
---|
326 | point = results[0].geometry.location;
|
---|
327 | }
|
---|
328 | event.lat = point.lat();
|
---|
329 | event.lng = point.lng();
|
---|
330 | dp.setUpdated(event.id, true, "updated");
|
---|
331 | }
|
---|
332 | );
|
---|
333 | }
|
---|
334 | };
|
---|
335 |
|
---|
336 | _delay = function(method, object, params, delay) {
|
---|
337 | setTimeout(function(){
|
---|
338 | var ret = method.apply(object,params);
|
---|
339 | method = obj = params = null;
|
---|
340 | return ret;
|
---|
341 | },delay||1000);
|
---|
342 | };
|
---|
343 |
|
---|
344 | scheduler.attachEvent("onEventChanged", function(event_id,event_object){
|
---|
345 | if(scheduler.is_visible_events(scheduler.getEvent(event_id))) {
|
---|
346 | scheduler.map._markers[event_id].setMap(null);
|
---|
347 | var event = scheduler.getEvent(event_id);
|
---|
348 | _displayEventOnMap(event);
|
---|
349 | } else {
|
---|
350 | scheduler.map._infowindow.close();
|
---|
351 | scheduler.map._markers[event_id].setMap(null);
|
---|
352 | }
|
---|
353 | return true;
|
---|
354 | });
|
---|
355 |
|
---|
356 | scheduler.attachEvent("onEventIdChange", function(old_event_id,new_event_id){
|
---|
357 | if(scheduler.is_visible_events(scheduler.getEvent(new_event_id))) {
|
---|
358 | if(scheduler.map._markers[old_event_id]) scheduler.map._markers[old_event_id].setMap(null);
|
---|
359 | var event = scheduler.getEvent(new_event_id);
|
---|
360 | _displayEventOnMap(event);
|
---|
361 | }
|
---|
362 | return true;
|
---|
363 | });
|
---|
364 |
|
---|
365 | /* Test/example
|
---|
366 | scheduler.attachEvent("onLocationError", function(event_id,event_object){
|
---|
367 | return new google.maps.LatLng(8, 8);
|
---|
368 | });
|
---|
369 | */
|
---|
370 |
|
---|
371 | scheduler.attachEvent("onBeforeEventDelete", function(event_id,event_object){
|
---|
372 | if (scheduler.map._markers[event_id]) {
|
---|
373 | scheduler.map._markers[event_id].setMap(null); // if new event is deleted tab != map then it doesn't have marker yet
|
---|
374 | }
|
---|
375 | scheduler.map._infowindow.close();
|
---|
376 | return true;
|
---|
377 | });
|
---|
378 |
|
---|
379 | scheduler._event_resolve_delay = 500;
|
---|
380 | scheduler.attachEvent("onEventLoading", function(event){
|
---|
381 | if(scheduler.config.map_resolve_event_location && event.event_location && !event.lat && !event.lng) { // don't delete !event.lat && !event.lng as location could change
|
---|
382 | scheduler._event_resolve_delay += 500;
|
---|
383 | _delay(_updateEventLocation,this,[event], scheduler._event_resolve_delay);
|
---|
384 | }
|
---|
385 | return true;
|
---|
386 | });
|
---|
387 |
|
---|
388 | scheduler.attachEvent("onEventCancel", function(event_id, is_new){
|
---|
389 | if(is_new) {
|
---|
390 | if(scheduler.map._markers[event_id])
|
---|
391 | scheduler.map._markers[event_id].setMap(null);
|
---|
392 | scheduler.map._infowindow.close();
|
---|
393 | }
|
---|
394 | return true;
|
---|
395 | });
|
---|
396 | }); |
---|