PluginProbe
CBX Map for Google Map & OpenStreetMap / trunk
CBX Map for Google Map & OpenStreetMap vtrunk
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 / cbxgooglemap-edit.js

cbxgooglemap-edit.js in CBX Map for Google Map & OpenStreetMap trunk, at assets/js/cbxgooglemap-edit.js

683 lines 29.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function ($) {
2 'use strict';
3
4 function cbxgogolemap_copyStringToClipboard(str) {
5 // Create new element
6 var el = document.createElement('textarea');
7 // Set value (string to be copied)
8 el.value = str;
9 // Set non-editable to avoid focus and move outside of view
10 el.setAttribute('readonly', '');
11 el.style = {position: 'absolute', left: '-9999px'};
12 document.body.appendChild(el);
13 // Select text inside element
14 el.select();
15 // Copy text to clipboard
16 document.execCommand('copy');
17 // Remove temporary element
18 document.body.removeChild(el);
19 }//end function cbxgogolemap_copyStringToClipboard
20
21 $(document).ready(function ($) {
22 var cbxgooglemap_awn_options = {
23 labels: {
24 tip: cbxgooglemap_edit.awn_options.tip,
25 info: cbxgooglemap_edit.awn_options.info,
26 success: cbxgooglemap_edit.awn_options.success,
27 warning: cbxgooglemap_edit.awn_options.warning,
28 alert: cbxgooglemap_edit.awn_options.alert,
29 async: cbxgooglemap_edit.awn_options.async,
30 confirm: cbxgooglemap_edit.awn_options.confirm,
31 confirmOk: cbxgooglemap_edit.awn_options.confirmOk,
32 confirmCancel: cbxgooglemap_edit.awn_options.confirmCancel
33 }
34 };
35
36 //console.log(cbxgooglemap_edit);
37
38 /*
39 if (cbxgooglemap_edit.api_key == '' && cbxgooglemap_edit.map_source == 1) {
40 new AWN().info(cbxgooglemap_edit.no_api_key, {
41 durations: {alert: 0},
42 icons: {enabled: false }
43 });
44 }*/
45
46 let notifier = new AWN(cbxgooglemap_awn_options);
47
48 var $cbxmap = null;
49
50 //Initiate Color Picker
51 //$('.cbxgooglemapmeta_colorpicker').wpColorPicker();
52
53 $('.selecttwo-select').select2({
54 placeholder: cbxgooglemap_edit.please_select,
55 allowClear: false
56 });
57
58
59 $(document).on('click', '.cbxgooglemapmeta_filepicker_btn', function (event) {
60 event.preventDefault();
61
62 var self = $(this);
63
64 // Create the media frame.
65 var file_frame = wp.media.frames.file_frame = wp.media({
66 title: self.data('uploader_title'),
67 button: {
68 text: self.data('uploader_button_text')
69 },
70 multiple: false
71 });
72
73 file_frame.on('select', function () {
74 var attachment = file_frame.state().get('selection').first().toJSON();
75
76 var picker_wrapper = self.closest('.cbxgooglemapmeta_input_file_wrap');
77
78 picker_wrapper.find('.cbxgooglemapmeta_filepicker').val(attachment.url);
79 picker_wrapper.find('.cbxgooglemapmeta_marker').css({
80 'background-image': 'url("' + attachment.url + '")'
81 }).removeClass('cbxgooglemapmeta_marker_hide');
82 picker_wrapper.find('.cbxgooglemapmeta_trash').removeClass('cbxgooglemapmeta_trash_hide');
83 picker_wrapper.find('.cbxgooglemapmeta_filepicker_btn').addClass('cbxgooglemapmeta_filepicked').removeClass('cbxgooglemapmeta_left_space');
84 });
85
86 // Finally, open the modal
87 file_frame.open();
88 });
89
90 // for icon delete functionality
91 $(document).on('click', '.cbxgooglemapmeta_input_file_wrap .cbxgooglemapmeta_trash', function () {
92 var picker_wrapper = $(this).closest('.cbxgooglemapmeta_input_file_wrap');
93 picker_wrapper.find('.cbxgooglemapmeta_input_file').val('');
94 picker_wrapper.find('.cbxgooglemapmeta_marker').addClass('cbxgooglemapmeta_marker_hide');
95 picker_wrapper.find('.cbxgooglemapmeta_filepicker_btn').removeClass('cbxgooglemapmeta_filepicked').addClass('cbxgooglemapmeta_left_space');
96 $(this).addClass('cbxgooglemapmeta_trash_hide');
97 });
98
99 // Switches option sections
100 $('.metabox-content-cbxgooglemap').hide();
101 var activetab = '';
102 if (typeof (localStorage) !== 'undefined') {
103 activetab = localStorage.getItem('cbxgooglemapmetaactivetab');
104
105 }
106 if (activetab !== '' && $(activetab).length) {
107 $(activetab).fadeIn();
108 } else {
109 $('.metabox-content-cbxgooglemap:first').fadeIn();
110 }
111
112 $('.metabox-content-cbxgooglemap .collapsed').each(function () {
113 $(this).find('input:checked').parent().parent().parent().nextAll().each(
114 function () {
115 if ($(this).hasClass('last')) {
116 $(this).removeClass('hidden');
117 return false;
118 }
119 $(this).filter('.hidden').removeClass('hidden');
120 });
121 });
122
123
124 if (activetab !== '' && $(activetab + '-tab').length) {
125 $(activetab + '-tab').addClass('nav-tab-active');
126
127 if (activetab + '-tab' === '#metabox-contentmaplocation-tab') {
128 cbxgooglemapmeta_render();
129 }
130 } else {
131 $('.nav-tab-wrapper a:first').addClass('nav-tab-active');
132 }
133
134 $('.nav-tab-wrapper a').on('click', function (evt) {
135 evt.preventDefault();
136
137 $('.nav-tab-wrapper a').removeClass('nav-tab-active');
138 $(this).addClass('nav-tab-active').blur();
139 var clicked_group = $(this).attr('href');
140 if (typeof (localStorage) !== 'undefined') {
141 localStorage.setItem('cbxgooglemapmetaactivetab', $(this).attr('href'));
142 }
143 $('.metabox-content-cbxgooglemap').hide();
144 $(clicked_group).fadeIn();
145
146
147 if ($(this).attr('id') == 'metabox-contentmaplocation-tab' && typeof $cbxmap !== null) {
148 cbxgooglemapmeta_render();
149 }
150 });
151
152 var cbxmap = '';
153
154
155 function cbxgooglemapmeta_render() {
156 //backend map integration
157 $('.cbxgooglemapmeta_input_location').each(function (index, element) {
158 var $element = $(element);
159
160 var $parent = $element.closest('.metabox-holder-cbxgooglemap');
161
162
163 var $zoom = $parent.find('.cbxgooglemapmeta_input_zoom');
164 var $zoom_val = Number($zoom.val());
165 var $show_info = Number($("input[name='_cbxgooglemapshowinfo']:checked").val());
166 var $info_open = Number($("input[name='_cbxgooglemapinfow_open']:checked").val());
167 var $scroll_wheel = Number($("input[name='_cbxgooglemapscrollwheel']:checked").val());
168
169
170 var $heading = $parent.find('.cbxgooglemapmeta_input_title').val();
171 var $address = $parent.find('.cbxgooglemapmeta_input_address').val();
172 var $website = $parent.find('.cbxgooglemapmeta_input_website').val();
173
174
175 var $lat = $('#metabox-contentmaplocation .cbxgooglemapmeta_input_lat');
176 var $lng = $('#metabox-contentmaplocation .cbxgooglemapmeta_input_lng');
177 var $current_lat = Number($lat.val());
178 var $current_lng = Number($lng.val());
179 var $icon_url = $('#metabox-contentmaplocation').find('.cbxgooglemapmeta_filepicker').val();
180
181
182 if (!$icon_url) {
183 $icon_url = cbxgooglemap_edit.icon_url_default;
184 }
185
186 var $meta_map = $parent.find('.map_canvas');
187 var $map_source = Number($meta_map.data('mapsource'));
188 var $map_type = $("select[name='_cbxgooglemapmaptype']").val();
189 var $api_key = $meta_map.data('apikey');
190
191 if ($map_source === 1) {
192 //google map
193 if ($api_key !== '') {
194 // The location of Primary marker
195 var $latlng = {lat: $current_lat, lng: $current_lng};
196
197 // The map, centered at Primary marker
198 $cbxmap = new google.maps.Map($meta_map[0], {
199 zoom: $zoom_val,
200 center: $latlng,
201 mapTypeId: $map_type,
202 disableDefaultUI: true
203 });
204
205 // Make sure you load Google Maps with the Places library:
206 // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
207
208 // Attach autocomplete to your input element
209 var input = $element[0]; // jQuery to raw DOM element
210 var autocomplete = new google.maps.places.Autocomplete(input);
211
212 // Optional: bias search results to the map’s current viewport
213 autocomplete.bindTo("bounds", $cbxmap);
214
215 // Handle when a user selects a place from the dropdown
216 autocomplete.addListener("place_changed", function () {
217 var place = autocomplete.getPlace();
218
219 if (!place.geometry || !place.geometry.location) {
220 //alert("No details available for input: '" + place.name + "'");
221 notifier.alert(cbxgooglemap_edit.no_address_found);
222 return;
223 }
224
225 // If the place has a viewport, fit map to it. Otherwise, center directly.
226 if (place.geometry.viewport) {
227 $cbxmap.fitBounds(place.geometry.viewport);
228 } else {
229 $cbxmap.setCenter(place.geometry.location);
230 $cbxmap.setZoom(15); // default zoom if no viewport
231 }
232
233 // Update marker position
234 $marker.setPosition(place.geometry.location);
235
236 // Update hidden fields
237 $lat.val(place.geometry.location.lat());
238 $lng.val(place.geometry.location.lng());
239
240 // Optional: update zoom field if you have one
241 $zoom.val($cbxmap.getZoom());
242
243 // Debug: see what you got
244 //console.log("Selected place:", place);
245 //console.log("Formatted address:", place.formatted_address);
246 //console.log("Components:", place.address_components);
247
248
249 // ===== Address breakdown =====
250 var address1 = "";
251 var address2 = "";
252
253 if (place.address_components) {
254 var street_number = "";
255 var route = "";
256 var city = "";
257 var state = "";
258 var postal = "";
259 var country = "";
260
261 place.address_components.forEach(function (comp) {
262 if (comp.types.includes("street_number")) {
263 street_number = comp.long_name;
264 }
265 if (comp.types.includes("route")) {
266 route = comp.long_name;
267 }
268 if (comp.types.includes("locality")) {
269 city = comp.long_name;
270 }
271 if (comp.types.includes("administrative_area_level_1")) {
272 state = comp.short_name;
273 }
274 if (comp.types.includes("postal_code")) {
275 postal = comp.long_name;
276 }
277 if (comp.types.includes("country")) {
278 country = comp.long_name;
279 }
280 });
281
282 // Line 1: street number + route
283 address1 = (street_number + " " + route).trim();
284
285 // Line 2: city, state postal, country
286 address2 = [city, state, postal, country].filter(Boolean).join(", ");
287 }
288
289 // Put into your field (format: line1, line2)
290 $parent.find(".cbxgooglemapmeta_input_address").val(address1 + (address2 ? ", " + address2 : ""));
291 });
292
293
294 if ($icon_url == '') {
295 /*var $map_icon = {
296 url: $icon_url,
297 scaledSize: new google.maps.Size(50, 50)
298 };*/
299
300 $marker = new google.maps.Marker({
301 position: $latlng,
302 map: $cbxmap,
303 title: $heading,
304 draggable: true,
305 //icon: $map_icon,
306 });
307 } else {
308 var $map_icon = {
309 url: $icon_url,
310 scaledSize: new google.maps.Size(50, 50)
311 };
312
313 $marker = new google.maps.Marker({
314 position: $latlng,
315 map: $cbxmap,
316 title: $heading,
317 draggable: true,
318 icon: $map_icon,
319 });
320 }
321
322
323 if ($show_info) {
324 var $info_content = '';
325 var $heading_html = '';
326 var $address_html = '';
327
328 if ($heading !== '') {
329 if ($website) {
330 $heading_html = '<h3 class="jqcbxgoglemap_info_heading"><a href="' + $website + '" target="_blank">' + $heading + '</a></h3>';
331 } else {
332 $heading_html = '<h3 class="jqcbxgoglemap_info_heading">' + $heading + '</h3>';
333 }
334 }
335
336 if ($address !== '') {
337 $address_html = '<div class="jqcbxgoglemap_info_body">' + $address + '</div>';
338 }
339
340
341 if ($heading_html !== '' || $address_html !== '') {
342 $info_content = '<div class="jqcbxgoglemap_info">' + $heading_html + ' ' + $address_html + '</div>';
343 }
344
345 // info popup
346 var infowindow = new google.maps.InfoWindow({
347 content: $info_content
348 });
349
350 $marker.addListener('click', function () {
351 infowindow.open({
352 anchor: $marker,
353 $cbxmap
354 });
355 });
356
357 if ($info_open) {
358 infowindow.open({
359 anchor: $marker,
360 $cbxmap
361 });
362 }
363 }
364
365 $marker.addListener('dragend', function (e) {
366 $lat.val(e.latLng.lat());
367 $lng.val(e.latLng.lng());
368 });
369
370
371 }//end if apy key exits
372
373 } else {
374 //open street map
375
376 //at first destroy the map
377 if ($cbxmap && $cbxmap.remove) {
378 $cbxmap.off();
379 $cbxmap.remove();
380 }
381
382 $cbxmap = L.map($meta_map[0]).setView([$current_lat, $current_lng], $zoom_val);
383
384 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
385 attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
386 }).addTo($cbxmap);
387
388
389 // Add OSM geocoder control
390 //json data https://gist.github.com/manchumahara/c4a81781c3bec1588b175ae762f8f8e5
391 var osmGeocoder = L.Control.geocoder({
392 geocoder: new L.Control.Geocoder.Nominatim(),
393 placeholder: cbxgooglemap_edit.search_address,
394 defaultMarkGeocode: false,
395 collapsed: false,
396 position: 'topright'
397 }).on('markgeocode', function (e) {
398 var bbox = e.geocode.bbox;
399 var center = bbox.getCenter();
400 var geocode = e.geocode;
401
402 // Update map view and marker position
403 $cbxmap.setView(center, $cbxmap.getZoom());
404 $marker.setLatLng(center);
405 $lat.val(center.lat);
406 $lng.val(center.lng);
407
408 // Get additional information from the geocode result
409 if (geocode.properties && geocode.properties.address) {
410 var address = geocode.properties.address;
411
412 // Build address line 1
413 var addressLine1 = '';
414 if (address.house_number) {
415 addressLine1 += address.house_number + ' ';
416 }
417 if (address.road) {
418 addressLine1 += address.road;
419 }
420
421 // Build address line 2
422 var addressLine2 = '';
423 if (address.suburb) {
424 addressLine2 += address.suburb;
425 } else if (address.neighbourhood) {
426 addressLine2 += address.neighbourhood;
427 } else if (address.district) {
428 addressLine2 += address.district;
429 }
430
431 // Combine address lines
432 var fullAddress = addressLine1;
433 if (addressLine1 && addressLine2) {
434 fullAddress += ', ' + addressLine2;
435 } else if (addressLine2) {
436 fullAddress = addressLine2;
437 }
438
439 // Update the address field
440 if (fullAddress) {
441 $parent.find('.cbxgooglemapmeta_input_address').val(fullAddress);
442 }
443
444 // Update other address components if corresponding fields exist
445 /*if (address.city || address.town || address.village) {
446 var city = address.city || address.town || address.village;
447 var cityField = $parent.find('.cbxgooglemapmeta_input_city');
448 if (cityField.length) {
449 cityField.val(city);
450 }
451 }
452
453 if (address.state || address.county) {
454 var state = address.state || address.county;
455 var stateField = $parent.find('.cbxgooglemapmeta_input_state');
456 if (stateField.length) {
457 stateField.val(state);
458 }
459 }
460
461 if (address.country) {
462 var countryField = $parent.find('.cbxgooglemapmeta_input_country');
463 if (countryField.length) {
464 countryField.val(address.country);
465 }
466 }
467
468 if (address.postcode) {
469 var postcodeField = $parent.find('.cbxgooglemapmeta_input_postcode');
470 if (postcodeField.length) {
471 postcodeField.val(address.postcode);
472 }
473 }*/
474 }
475
476 // Update heading if display_name is available and no heading is set
477 //if (geocode.name && !$parent.find('.cbxgooglemapmeta_input_location').val()) {
478 if (geocode.name) {
479 //$parent.find('.cbxgooglemapmeta_input_title').val(geocode.name);
480 $parent.find('.cbxgooglemapmeta_input_location').val(geocode.name);
481 }
482
483 // Fit map to bounding box if it's reasonable
484 if (bbox.getNorthEast().distanceTo(bbox.getSouthWest()) < 10000) { // 10km
485 $cbxmap.fitBounds(bbox);
486 $zoom.val($cbxmap.getZoom());
487 }
488 }).addTo($cbxmap);
489
490 // Enable search as you type
491 var geocoderInput = $('.leaflet-control-geocoder-form input');
492 var searchTimeout;
493
494 geocoderInput.on('input', function () {
495 var query = $(this).val();
496
497 // Clear previous timeout
498 clearTimeout(searchTimeout);
499
500 // Only search if we have at least 3 characters
501 if (query.length >= 3) {
502 // Set a new timeout to avoid too many requests while typing
503 searchTimeout = setTimeout(function () {
504 // Trigger the geocoder search
505 osmGeocoder._geocode(query);
506 }, 300); // 300ms delay
507 }
508 });
509
510 // Override the geocoder's _markGeocode method to ensure our event handler is called
511 var originalMarkGeocode = osmGeocoder._markGeocode;
512 osmGeocoder._markGeocode = function (result) {
513 // Call the original method
514 originalMarkGeocode.call(this, result);
515
516 // Trigger our custom event
517 this.fire('markgeocode', {
518 geocode: result
519 });
520 };
521
522 // Enable search as you type
523 var geocoderInput = $('.leaflet-control-geocoder-form input');
524 var searchTimeout;
525
526 geocoderInput.on('input', function () {
527 var query = $(this).val();
528
529 // Clear previous timeout
530 clearTimeout(searchTimeout);
531
532 // Only search if we have at least 3 characters
533 if (query.length >= 3) {
534 // Set a new timeout to avoid too many requests while typing
535 searchTimeout = setTimeout(function () {
536 // Trigger the geocoder search
537 osmGeocoder._geocode(query);
538 }, 300); // 300ms delay
539 }
540 });
541
542 // Override the geocoder's _markGeocode method to ensure our event handler is called
543 var originalMarkGeocode = osmGeocoder._markGeocode;
544 osmGeocoder._markGeocode = function (result) {
545 // Call the original method
546 originalMarkGeocode.call(this, result);
547
548 // Trigger our custom event
549 this.fire('markgeocode', {
550 geocode: result
551 });
552 };
553
554
555 var $marker;
556
557 if ($icon_url !== '') {
558 var $map_icon = L.icon({
559 iconUrl: $icon_url,
560 iconSize: [50, 50],
561 popupAnchor: [15, 0]
562 });
563
564 $marker = L.marker([$current_lat, $current_lng], {
565 draggable: true,
566 icon: $map_icon
567 }).addTo($cbxmap);
568 } else {
569 $marker = L.marker([$current_lat, $current_lng], {
570 draggable: true
571 }).addTo($cbxmap);
572 }
573
574
575 if ($show_info === 1) {
576 var $heading_html = '';
577 var $address_html = '';
578
579 if ($heading !== '') {
580 if ($website) {
581 $heading_html = '<h3 class="jqcbxgoglemap_info_heading"><a href="' + $website + '" target="_blank">' + $heading + '</a></h3>';
582 } else {
583 $heading_html = '<h3 class="jqcbxgoglemap_info_heading">' + $heading + '</h3>';
584 }
585 }
586
587
588 if ($address !== '') {
589 $address_html = '<div class="jqcbxgoglemap_info_body">' + $address + '</div>';
590 }
591
592 if ($heading_html !== '' || $address_html !== '') {
593 if ($info_open) {
594 $marker.bindPopup('<div class="jqcbxgoglemap_info">' + $heading_html + '' + $address_html + '</div>').openPopup();
595 } else {
596 $marker.bindPopup('<div class="jqcbxgoglemap_info">' + $heading_html + '' + $address_html + '</div>').on('click', function (event) {
597 //event.target.openPopup;
598 });
599 }
600 }
601 }
602
603 if ($scroll_wheel === 1) {
604 $cbxmap.scrollWheelZoom.disable();
605 }
606
607 $marker.on('dragend', function (e) {
608 $lat.val($marker.getLatLng().lat);
609 $lng.val($marker.getLatLng().lng);
610 });
611
612 $cbxmap.on('zoomend', function (e) {
613 $zoom.val($cbxmap.getZoom());
614 });
615
616
617 }//end if openstreetmap
618
619 CBXGOOGLEMAPEvents_do_action('cbxgooglemap_render_meta', $parent.find('.map_canvas'), $cbxmap, $map_source);
620
621
622 });//end google map
623 }
624
625
626 //select shortcode text and copy to clipboard
627 /*$(document).on('click', '.cbxgooglemapshortcodecopytrigger', function (e) {
628
629 var text = $(this).data('clipboard-text');
630 var successText = $(this).data('success');
631 var $input = $('<input class="cbxgooglemapshortcode-text" type="text">');
632 $input.prop('value', text);
633 $input.insertAfter('body');
634 $input.select();
635
636 try {
637 document.execCommand('copy');
638 $('.cbxgooglemapshortcode-text').remove();
639 $(this).after('<span id="copied-text">' + successText + '</span>');
640 $('#copied-text').fadeOut(1000, function () {
641 $(this).remove();
642 });
643 } catch (err) {
644
645 }
646 });*/
647
648
649 //click to copy shortcode
650 $('.cbxballon_ctp').on('click', function (e) {
651 e.preventDefault();
652
653 var $this = $(this);
654 cbxgogolemap_copyStringToClipboard($this.prev('.cbxshortcode').text());
655
656 $this.attr('aria-label', cbxgooglemap_edit.copycmds.copied_tip);
657
658 window.setTimeout(function () {
659 $this.attr('aria-label', cbxgooglemap_edit.copycmds.copy_tip);
660 }, 1000);
661 });
662
663 $('.wrap').addClass('cbx-chota cbxgooglemap-page-wrapper cbxgooglemap-addedit-wrapper');
664 $('#search-submit').addClass('button primary');
665 $('#post-query-submit').addClass('button primary');
666 $('.button.action').addClass('button primary');
667 $('.save-post-status').addClass('button primary mt-10');
668 $('.save-post-visibility').addClass('button primary mt-10');
669 $('.save-timestamp').addClass('button primary mt-10');
670 $('.preview.button').addClass('button secondary');
671 $('.button.tagadd').addClass('button secondary');
672 $('.cancel-post-status').addClass('button secondary mt-10');
673 $('.cancel-post-visibility').addClass('button secondary mt-10');
674 $('.cancel-timestamp').addClass('button secondary mt-10');
675 $('.page-title-action').addClass('button primary');
676 $('#save-post').addClass('button primary');
677 $('#publish').addClass('button primary');
678 $('#screen-meta').addClass('cbx-chota cbxgooglemap-page-wrapper cbxgooglemap-logs-wrapper');
679 $('#screen-options-apply').addClass('primary');
680 $('#title').attr('placeholder', cbxgooglemap_edit.map_title_placeholder);
681
682 });
683 })(jQuery);