1/*! 2 * 3 * mtcGoogleMaps.js - A jQuery plugin for google maps 4 * Version : 1.0 5 * Author(s) : Valdis Ceirans, Lee Methven 6 * 7 * Docs: http://wiki.mtcmedia.co.uk/index.php?title=Jquery_Plugin_-_mtc_google_maps 8 * Website: http://www.mtcmedia.co.uk 9 * 10 */ 11 12 13/* 14 * Function for handling the enabling / disabling of filters 15 */ 16 17function labelFilters(plugin) { 18 $('.js_mapLabel').each(function () { 19 var category_code = $(this).data('category-code'), 20 state = true; 21 22 if ($(this).hasClass('off')) { 23 state = false; 24 // hide ones within list view too 25 $('li[data-category-code="' + category_code + '"]').fadeOut(); 26 } else { 27 state = true; 28 // show ones within list view too 29 $('li[data-category-code="' + category_code + '"]').fadeIn(); 30 } 31 32 $.each(plugin.places, function (i, value) { 33 if (typeof (value.category_code) !== 'undefined' && value.category_code === category_code) { 34 value.marker.setVisible(state); 35 } 36 }); 37 }); 38} 39 40function initGoogleMaps() { 41 'use strict'; 42 43 var js_path = "/sites/scottishwater/js/plugins/includes/"; 44 45 $.getScript(js_path + "infobox.js", function (data, textStatus, jqxhr) { 46 $('.googleMap').each(function (i, elem) { 47 $(elem).data('plugin_mtcGoogleMaps').init(); 48 }); 49 }); 50 51 $('body').on('click', '.js_focusMarker', function (e) { 52 53 e.preventDefault(); 54 55 var anchor = $(this), 56 plugin, place, map, 57 toShow = anchor.closest('li').find('.stockistInfoWrap'), 58 toHide = $('#stockistResults .stockistInfoWrap:not(#' + toShow.attr('id') + ')'); 59 60 //hide showing stockist, show clicked 61 toHide.stop(true, true).slideUp(); 62 toShow.stop(true, true).slideDown(); 63 64 map = $('#map' + $(this).data('map-id')); 65 66 plugin = map.data('plugin_mtcGoogleMaps'); 67 68 place = plugin.places[$(this).data('place-id')]; 69 70 plugin.google_map.panTo(place.marker.getPosition()); 71 72 }); 73} 74 75; (function ($, window, document, undefined) { 76 77 78 // Create the defaults once 79 var plugin_name = "mtcGoogleMaps", 80 data_key = "plugin_" + plugin_name; 81 82 $.fn[plugin_name] = function (options) { 83 var load_called = $('body').hasClass('hasGMapsApi'), 84 plugin = this, 85 plugin_api_key, 86 script; 87 88 // Pop out the error message 89 if (this.length === 0) { 90 return this; 91 } 92 93 // call init 94 if (this.length > 0) { 95 //load google js async 96 if (!load_called) { 97 if (typeof google === 'undefined' || typeof google.maps === 'undefined') { 98 plugin_api_key = $('body').data('maps-api-key'); 99 script = document.createElement('script'); 100 script.type = 'text/javascript'; 101 script.src = '//maps.googleapis.com/maps/api/js?key=' + plugin_api_key + '&libraries=places&callback=initGoogleMaps'; 102 document.body.appendChild(script); 103 } else { 104 initGoogleMaps(); 105 } 106 $('body').addClass('hasGMapsApi'); 107 } 108 //for each of the elements call plugin 109 return this.each(function (index, el) { 110 var plugin, _name; 111 plugin = $.data(this, data_key); 112 if (typeof options === 'string') { 113 return plugin !== null ? typeof plugin[_name = options] === "function" ? plugin[_name]() : void 0 : void 0; 114 } else if (!plugin) { 115 $(el).addClass('googleMap'); 116 return $.data(this, data_key, new Plugin(el, options)); 117 } 118 }); 119 120 } 121 122 }; 123 //sort points by proximity 124 function sortPointsByProximity(location, places, search_distance) { 125
126 var points_sorted = [], 127 index, 128 marker_place, 129 dif; 130 131 for (index = 0; index < places.length; index++) { 132 133 marker_place = places[index].marker.getPosition(); 134 dif = PythagorasEquirectangular(location.lat(), location.lng(), marker_place.lat(), marker_place.lng()); 135 136 if (search_distance >= dif) { 137 points_sorted.push({ 138 dif: dif, 139 id: index 140 }); 141 } 142 } 143 144 points_sorted.sort(compareByDif); 145 return points_sorted; 146 } 147 //compare 2 distances 148 function compareByDif(a, b) { 149 if (a.dif < b.dif) { 150 return -1; 151 } 152 if (a.dif > b.dif) { 153 return 1; 154 } 155 return 0; 156 } 157 158 function getFirstKey(data) { 159 for (elem in data) { 160 return elem; 161 } 162 } 163 //calculate distance 164 function PythagorasEquirectangular(lat1, lon1, lat2, lon2) { 165 lat1 = Deg2Rad(lat1); 166 lat2 = Deg2Rad(lat2); 167 lon1 = Deg2Rad(lon1); 168 lon2 = Deg2Rad(lon2); 169 var R = 6371; // km 170 var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2); 171 var y = (lat2 - lat1); 172 var d = Math.sqrt(x * x + y * y) * R; 173 return d; 174 } 175 // Convert Degress to Radians 176 function Deg2Rad(deg) { 177 return deg * Math.PI / 180; 178 } 179 // The actual plugin constructor 180 function Plugin(elem, options) { 181 this.element = elem; 182 this.settings = null; 183 this.options = options; 184 this._name = plugin_name; 185 this.map_id = 0; 186 this.places = []; 187 this.places_count = 0; 188 this.google_map = null; 189 this.info_box = null; 190 map_count = 0; 191 geocoder = null; 192 } 193 194 Plugin.prototype = { 195 //init funciton 196 init: function () { 197 var plugin = this, 198 autocomplete, 199 defaults = { 200 marker: { 201 icon: null, 202 width: null, 203 height: null, 204 origin_x: null, 205 origin_y: null, 206 anchor_x: null, 207 anchor_y: null, 208 optimized: null 209 }, 210 info_box: { 211 close_button_markup: '<button>x</button>', 212 width: 200, 213 offset_x: -100, 214 offset_y: -50, 215 align_bottom: true, 216 close_on_click: true, 217 disable_auto_pan: false, 218 info_box_class: 'infobox' 219 }, 220 search: { 221 distance: 100, 222 max_results: 3, 223 no_results_markup: '<p>Sorry, no places nearby were found.</p>', 224 nothing_found_markup: '', 225 result_zoom: 8, 226 search_results: '', 227 search_form: '', 228 autocomplete: false, 229 clear_button_class: 'buttonAlt buttonOutline', 230 clear_button_text: 'Clear Results', 231 url_query_check: false, 232 url_query_param: '' 233 }, 234 directions: false, 235 directions_options: { 236 directions_form: '.js_googleMapsSearchForm', 237 directions_output: '.js_mapOutputPanel', 238 onDirectionsLoad: function () { } 239 }, 240 map_options: { 241 mapTypeId: google.maps.MapTypeId.ROADMAP, 242 disableDefaultUI: false, 243 scrollwheel: false, 244 fullscreenControl: false, 245 streetViewControl: false, 246 mapTypeControl: false 247 }, 248 styles: null, 249 responsive: [ 250 { 251 breakpoint: 640, 252 settings: { 253 } 254 } 255 ],
256 custom_overlay: false 257 }; 258 259 this.map_id = map_count; 260 ++map_count; 261 262 // read the settings and sort them by breakpoints 263 plugin.all_settings = $.extend(true, {}, defaults, this.options); 264 plugin.settings = null; 265 plugin.readAllOptions(); 266 plugin.checkBreakpoints(); 267 268 // trigger map load 269 plugin.loadMaps(); 270 271 // stockist search 272 plugin.initSearch(); 273 274 if ($(plugin.settings.directions_options.directions_form).length > 0 && plugin.settings.directions === true) { 275 plugin.initDirections(); 276 } 277 }, 278 279 fitAllBounds: function (b) { 280 var plugin = this; 281 // Get north east and south west markers bounds coordinates 282 var ne = b.getNorthEast(), 283 sw = b.getSouthWest(), 284 map = plugin.google_map; 285 // Get the current map bounds 286 var mapBounds = map.getBounds(); 287 // Check if map bounds contains both north east and south west points 288 if (mapBounds.contains(ne) && mapBounds.contains(sw)) { 289 // Everything fits 290 return; 291 } else { 292 var mapZoom = map.getZoom(); 293 if (mapZoom > 0) { 294 // Zoom out 295 map.setZoom(mapZoom - 1); 296 // Try again 297 plugin.fitAllBounds(b); 298 } 299 } 300 }, 301 302 initSearch: function () { 303 var plugin = this, 304 search_settings = plugin.settings.search, 305 search_form = $(search_settings.search_form), 306 search_input = search_form.find('input'), 307 search_button = search_form.find('button'), 308 clear_button, 309 results_place = $(search_settings.search_results); 310 311 if (search_form.length > 0 && $(search_settings.search_results).length > 0) { 312 313 //aadd clear results button 314 clear_button = $('<a class="js_clearMapResults ' + search_settings.clear_button_class + '" href="#"></a>'); 315 clear_button.html(search_settings.clear_button_text); 316 search_form.append(clear_button); 317 318 //hide the button initially 319 clear_button.hide(); 320 321 //button click 322 search_button.on('click', function (e) { 323 e.preventDefault(); 324 plugin.findAddress(); 325 326 $('.js_error').remove(); 327 328 if (plugin.settings.in_your_area_map === true) { 329 // reset filter markers 330 $('.js_mapLabel').removeClass('off'); 331 $('.js_mapLabel .labelToggle').removeClass('off'); 332 } 333 334 }); 335 336 $('.js_clearMapResults').on('click', function (e) { 337 338 var initialLat = $('#initLat').val(); 339 var initialLng = $('#initLong').val(); 340 341 e.preventDefault(); 342 343 //reset the map 344 plugin.resetMap(); 345 346 // set zoom to focus on Scotland more 347 plugin.google_map.setZoom(8); 348 349 // set location to initial lat / lng set in sitecore 350 var clear_map_position = new google.maps.LatLng(initialLat, initialLng); 351 plugin.google_map.setCenter(clear_map_position); 352 353 //clear results 354 results_place.html(''); 355 356 if (plugin.settings.in_your_area_map === true) { 357 results_place.html(plugin.settings.search.nothing_found_markup); 358 } 359 360 //clear search 361 search_input.val(''); 362 search_input.focus(); 363 364 //hide the clear button 365 $('.js_clearMapResults').hide(); 366 367 $('.js_error').remove(); 368 369 if (plugin.settings.in_your_area_map === true) { 370 // reset filter markers 371 $('.js_mapLabel').removeClass('off'); 372 $('.js_mapLabel .labelToggle').removeClass('off'); 373 } 374 375 }); 376 377 //set autocomplete via geocoder
378 if (search_settings.autocomplete === true) { 379 autocomplete = new google.maps.places.Autocomplete(search_input.get(0)); 380 381 autocomplete.bindTo('bounds', plugin.google_map); 382 383 google.maps.event.addListener(autocomplete, 'place_changed', function () { 384 plugin.findAddress(); 385 }); 386 } 387 } 388 }, 389 390 initDirections: function () { 391 var plugin = this, 392 directions_options = plugin.settings.directions_options, 393 directions_form = directions_options.directions_form, 394 directions_output = directions_options.directions_output; 395 396 autocomplete = new google.maps.places.Autocomplete($(directions_form).find('input').get(0)); 397 398 $('body').on('submit', directions_form, function (e) { 399 400 e.preventDefault(); 401 402 // reset the map and directions 403 $(directions_output).empty(); 404 405 plugin.loadMaps(); 406 407 var directionsDisplay = new google.maps.DirectionsRenderer, 408 directionsService = new google.maps.DirectionsService, 409 origin = $(directions_form).find('input').val(), 410 destination; 411 412 directionsDisplay.setMap(plugin.google_map); 413 414 directionsDisplay.setPanel($(directions_output)[0]); 415 416 destination = plugin.places[0].marker.getPosition().lat() + ", " + plugin.places[0].marker.getPosition().lng(); 417 418 plugin.calculateAndDisplayRoute(directionsService, directionsDisplay, origin, destination); 419 420 // callback for when the directions has been added to the map 421 directions_options.onDirectionsLoad(); 422 }); 423 }, 424 425 // calcualte the route between two points 426 calculateAndDisplayRoute: function (directionsService, directionsDisplay, origin, destination) { 427 var plugin = this; 428 429 directionsService.route({ 430 origin: origin, 431 destination: destination, 432 travelMode: google.maps.TravelMode.DRIVING, 433 unitSystem: google.maps.UnitSystem.IMPERIAL 434 435 }, function (response, status) { 436 if (status === google.maps.DirectionsStatus.OK) { 437 directionsDisplay.setDirections(response); 438 } else { 439 $(plugin.settings.search.directions_output).html('<p class="error">No directions found for this request.</p>'); 440 } 441 }); 442 443 }, 444 445 //resets map state to inital after search 446 resetMap: function () { 447 448 var plugin = this, 449 bounds; 450 451 if (plugin.places.length > 0) { 452 bounds = new google.maps.LatLngBounds(); 453 bounds.extend(plugin.places[0].marker.getPosition()); 454 455 //if 'you' position is there hide it 456 if (typeof plugin.places.you !== 'undefined') { 457 plugin.places.you.setVisible(false); 458 } 459 460 //if loop through all places 461 $.each(plugin.places, function () { 462 463 //set visible 464 this.marker.setVisible(true); 465 466 bounds.extend(this.marker.getPosition()); 467 plugin.fitAllBounds(bounds); 468 }); 469 } 470 }, 471 472 resetMarkers: function () { 473 var plugin = this; 474 475 if (plugin.places.length > 0) { 476 477 //if 'you' position is there, don't hide it 478 if (typeof plugin.places.you !== 'undefined') { 479 plugin.places.you.setVisible(true); 480 } 481 482 //if loop through all places 483 $.each(plugin.places, function () { 484 // bring back markers 485 this.marker.setVisible(true); 486 }); 487 } 488 }, 489 490 // prepare the responsive array 491 readAllOptions: function () { 492 var plugin = this, 493 previous_breakpoints_settings = plugin.all_settings; 494 495 496 if (plugin.all_settings.responsive) { 497 498 // loop through responsive settings 499 $.each(plugin.all_settings.responsive, function (i, value) { 500 // extend breakpoints settings to include ones from previous 501 value.settings = $.extend(true, {}, previous_breakpoints_settings, value.settings); 502 // get rid of responsive duplicate 503 delete value.settings.responsive; 504 // previous now become the current ones 505 previous_breakpoints_settings = value.settings; 506 }); 507 508 } 509 }, 510 // go through the responsive settings and find the appropriate 511 checkBreakpoints: function () { 512 var window_width = $(window).width(), 513 plugin = this; 514 515 // set the default as desktop 516 plugin.settings = plugin.all_settings; 517 // iterate through settings and find the right one 518 if (plugin.all_settings.responsive) { 519 520 // loop through responsive settings 521 $.each(plugin.all_settings.responsive, function (i, value) { 522 // find one that is active 523 if (matchesMediaQuery(0, value.breakpoint)) { 524 plugin.settings = value.settings; 525 } 526 }); 527 } 528 529 }, 530 531 532 //plugin data to google maps 533 initMap: function (map) { 534 var plugin = this, 535 zoom = 8, 536 mapOptions, 537 infobox_options, 538 bounds = new google.maps.LatLngBounds(), 539 myLatlng, 540 contentString; 541
542 var initialLat = $('#initLat').val(); 543 var initialLng = $('#initLong').val(); 544 545 // handle on / off of map labels and also showing / hiding these within list view 546 $('body').on('swipe click', '.js_mapLabel', function (e) { 547 e.preventDefault(); 548 549 var category_code = $(this).data('category-code'), 550 state = true; 551 552 $(this).toggleClass('off'); 553 $(this).children('.labelToggle').toggleClass('off'); 554 555 if ($(this).hasClass('off')) { 556 state = false; 557 // hide ones within list view too 558 $('li[data-category-code="' + category_code + '"]').fadeOut(); 559 } else { 560 state = true; 561 // show ones within list view too 562 $('li[data-category-code="' + category_code + '"]').fadeIn(); 563 } 564 565 $.each(plugin.places, function (i, value) { 566 if (typeof (value.category_code) !== 'undefined' && value.category_code === category_code) { 567 value.marker.setVisible(state); 568 } 569 }); 570 }); 571 572 plugin.google_map = new google.maps.Map(map, plugin.settings.map_options); 573 574 // show markers on drag end, but only if filter is not selected / enabled 575 google.maps.event.addListener(plugin.google_map, 'dragend', function () { 576 labelFilters(plugin); 577 }); 578 579 if (plugin.places > 0) { 580 plugin.google_map.setCenter(new google.maps.LatLng(plugin.places[0].coords[0], plugin.places[0].coords[1])); 581 } 582 583 if (typeof ($(map).data('zoom')) !== "undefined") { 584 zoom = $(map).data('zoom'); 585 } 586 587 plugin.google_map.setZoom(zoom); 588 589 if (typeof (plugin.settings.styles) !== 'undefined') { 590 plugin.google_map.setOptions({ 591 styles: plugin.settings.styles 592 }); 593 } 594 595 infobox_options = { 596 alignBottom: plugin.settings.info_box.align_bottom, 597 content: 'loading..', 598 disableAutoPan: plugin.settings.disable_auto_pan, 599 maxWidth: 0, 600 pixelOffset: new google.maps.Size(plugin.settings.info_box.offset_x, plugin.settings.info_box.offset_y), 601 zIndex: null, 602 boxStyle: { 603 width: plugin.settings.info_box.width + "px" 604 }, 605 closeBoxMargin: "0", 606 closeButtonMarkup: plugin.settings.info_box.close_button_markup, 607 infoBoxClearance: new google.maps.Size(1, 1), 608 isHidden: false, 609 pane: "floatPane", 610 enableEventPropagation: false, 611 boxClass: plugin.settings.info_box.info_box_class 612 }; 613 614 plugin.info_box = new InfoBox(infobox_options); 615 616 $.each(plugin.places, function (i, value) { 617 618 var marker_icon, marker_image = null; 619 620 // if no specific marker icon for coordinates 621 if (typeof (value.marker_icon) !== 'undefined') { 622 marker_icon = value.marker_icon; 623 624 // if icon is defined in settings 625 } else if (typeof (plugin.settings.marker.icon) !== 'undefined') { 626 marker_icon = plugin.settings.marker.icon; 627 } 628 629 myLatlng = new google.maps.LatLng(value.coords[0], value.coords[1]); 630 631 value.marker = new google.maps.Marker({ 632 position: myLatlng, 633 map: plugin.google_map, 634 optimized: false 635 }); 636 637 if (typeof (marker_icon) !== 'undefined' && plugin.settings.marker.width !== null) { 638 marker_image = { 639 url: marker_icon, 640 size: new google.maps.Size(plugin.settings.marker.width, plugin.settings.marker.height), 641 origin: new google.maps.Point(plugin.settings.marker.origin_x, plugin.settings.marker.origin_y), 642 anchor: new google.maps.Point(plugin.settings.marker.anchor_x, plugin.settings.marker.anchor_y), 643 scaledSize: new google.maps.Size(plugin.settings.marker.width, plugin.settings.marker.height) 644 }; 645 value.marker.setIcon(marker_image); 646 } else if (typeof (marker_icon) !== 'undefined') { 647 marker_image = marker_icon; 648 value.marker.setIcon(marker_image); 649 } 650 651 bounds.extend(value.marker.getPosition()); 652 653 //add title and description 654 if (typeof (value.description) !== 'undefined' || typeof (value.title) !== 'undefined') { 655 value.marker.addListener('click', function () { 656 var titleMarkup = "", 657 descriptionMarkup = ""; 658 659 if (typeof (value.description) !== 'undefined') { 660 descriptionMarkup = value.description; 661 } 662 663 if (typeof (value.title) !== 'undefined') { 664 titleMarkup = '<h3>' + value.title + '</h3>'; 665 } 666 667 plugin.info_box.setContent('<div class="info_boxContent">' + titleMarkup + descriptionMarkup + '</div>'); 668 plugin.info_box.open(plugin.google_map, value.marker); 669 }); 670 } 671 672 // custom marker type, used within in your area map 673 if (plugin.settings.in_your_area_map === true) { 674 if (typeof (value.category_code) !== 'undefined' || typeof (value.marker_id) !== 'undefined') { 675 value.marker.addListener('click', function () { 676 var marker_type = value.marker_type, 677 marker_id = value.marker_id, 678 overlay_content = value.overlay_content, 679 title = overlay_content.overlay_title, 680 content = overlay_content.overlay_content, 681 link = overlay_content.link; 682 incidentNumber = overlay_content.incident_number; 683 684 // handle custom overlay if setting is true, built from json 685 if (plugin.settings.custom_overlay !== false && overlay_content !== '') { 686 $.openMtcOverlay({ 687 no_ajax: true, 688 target: '#inAreaMapOverlay', 689 content_class: 'contentOverlayWrap', 690 perfect_scroll: false, 691 max_width: 820, 692 button_html: '<div class="overlayCloseButton"><a href="#" class="closeButton"><img src="/sites/scottishwater/images/svgs/close-icon.svg" alt="Close"></a></div>', 693 beforeOpen: function () { 694 var element = $('.contentOverlay'); 695 696 element.find('h2').html(title); 697 element.find('.pageContent').html(content); 698 699 // if link is empty in json 700 if (link === '') { 701 element.find('.button').hide(); 702 } else { 703 element.find('.button').show().attr('href', link); 704 } 705 if (incidentNumber == '' || incidentNumber == undefined) { 706 element.find('.btnIncident').hide(); 707 } else { 708 var crmlink = $('#crmLink').val(); 709 if (crmlink == undefined || crmlink == null || crmlink == '') { 710 crmlink = 'https://swcustomerportal.microsoftcrmportals.com/ReportAProblem?casenumber='; 711 } 712 var url = crmlink + incidentNumber; 713 element.find('.btnIncident').show().attr('href', url); 714 } 715 } 716 }); 717 } 718 }); 719 } 720 } 721 }); 722 723 if (plugin.settings.info_box.close_on_click === true) { 724 google.maps.event.addListener(plugin.google_map, 'click', function () { 725 plugin.info_box.close(); 726 }); 727 } 728 729 if (plugin.places.length > 1) { 730 plugin.google_map.fitBounds(bounds); 731 plugin.google_map.panToBounds(bounds); 732 } 733 734 google.maps.event.addDomListener(window, "resize", function () { 735 var center = plugin.google_map.getCenter(); 736 google.maps.event.trigger(plugin.google_map, "resize"); 737 plugin.google_map.setCenter(center); 738 }); 739 740 // check for query string in first instance, if none, fall back to cookie check, before falling back to default location
741 if (plugin.settings.search.url_query_check === true && plugin.settings.search.url_query_param !== '' && $.QueryString[plugin.settings.search.url_query_param]) { 742 var query_param = $.QueryString[plugin.settings.search.url_query_param]; 743 744 if (query_param) { 745 plugin.findAddress(query_param); 746 747 // in your area map, populate location field 748 if (plugin.settings.in_your_area_map === true) { 749 $('.js_inYourAreaLocationInput').val(query_param); 750 } 751 } 752 } else if (Cookies.getJSON('HTML5GeoLocation')) { 753 var cookie = Cookies.getJSON('HTML5GeoLocation'), 754 user_postcode; 755 756 if (cookie.UserEnteredPostalCode === null) { 757 user_postcode = cookie.PostalCode; 758 } else { 759 user_postcode = cookie.UserEnteredPostalCode; 760 } 761 762 plugin.findAddress(user_postcode); 763 764 // in your area map, populate location field 765 if (plugin.settings.in_your_area_map === true) { 766 $('.js_inYourAreaLocationInput').val(user_postcode); 767 } 768 } else { 769 // set component restriction to false so lat / long can be used for location detection 770 var component_restriction = false; 771 plugin.findAddress(initialLat + ',' + initialLng, component_restriction); 772 773 // show markers on zoom in / out, but only on initial load 774 google.maps.event.addListener(plugin.google_map, 'zoom_changed', function () { 775 labelFilters(plugin); 776 }); 777 } 778 }, 779 780 //reads data to plugin 781 loadMaps: function () { 782 783 google.maps.visualRefresh = true; 784 785 var mapEl = $(this.element), 786 mapMode, 787 plugin = this, 788 place, 789 mapId; 790 791 geocoder = new google.maps.Geocoder(); 792 //for each map 793 mapEl.each(function (index, map) { 794 var place = {}, 795 zoomListener; 796 797 place.map_id = plugin.id; 798 799 // one or multiple coordinates 800 if ($(map).data('coords')) { 801 mapMode = 'single'; 802 } else if ($(map).data('coords-array')) { 803 mapMode = 'multiple'; 804 } else if ($(map).data('json-array')) { 805 mapMode = 'json'; 806 } else if ($(map).data('json-markers-array')) { 807 mapMode = 'markers'; 808 } 809 810 mapId = map_count - 1; 811 812 $(map).attr('id', 'map' + mapId); 813 814 //set map options 815 if (mapMode === 'single') { 816 817 place.coords = $(map).data('coords').split(','); 818 819 if (typeof ($(map).data('marker-icon')) !== 'undefined') { 820 place.marker_icon = $(map).data('marker-icon'); 821 } 822 if (typeof ($(map).data('title')) !== 'undefined') { 823 place.title = $(map).data('title'); 824 } 825 if (typeof ($(map).data('description')) !== 'undefined') { 826 place.description = $(map).data('description'); 827 } 828 829 plugin.places[plugin.places_count] = jQuery.extend({}, place); 830 ++plugin.places_count; 831 832 } else if (mapMode === 'multiple') { 833 var coordsArrayHolder = $($(this).data('coords-array')), 834 coordsArray = coordsArrayHolder.find('[data-coords]'); 835 836 if (coordsArray.length > 0) { 837 coordsArray.each(function (i, el) { 838 place.coords = $(this).data('coords').split(','); 839 840 place.marker_icon = $(this).data('marker-icon'); 841 842 if (typeof ($(map).data('title-selector')) !== 'undefined') { 843 place.title = $(this).find($(map).data('title-selector')).html(); 844 var link = $('<a/>', { 845 href: "#", 846 "data-map-id": map_count - 1, 847 "data-place-id": i, 848 class: 'js_focusMarker' 849 }); 850 851 $(this).find($(map).data('title-selector')).wrapInner(link); 852 } 853 854 if (typeof ($(map).data('description-selector')) !== 'undefined') { 855 place.description = $(this).find($(map).data('description-selector')).html(); 856 } 857 858 // $(this).data('marker-id', plugin.places.length); 859 plugin.places[plugin.places_count] = jQuery.extend({}, place); 860 ++plugin.places_count; 861 }); 862 } 863 864 } else if (mapMode === 'json') { 865 var arr = window[$(this).data('json-array')]; 866 $.each(arr, function (i, el) { 867 place.coords = el.coords.split(','); 868 869 if (typeof (el.marker_icon) !== 'undefined') { 870 place.marker_icon = el.marker_icon; 871 } 872 873 if (typeof (el.title) === 'string') { 874 place.title = el.title; 875 } 876 877 if (typeof (el.description) === 'string') { 878 place.description = el.description; 879 } 880 881 plugin.places[plugin.places_count] = jQuery.extend({}, place); 882 ++plugin.places_count; 883 }); 884 } else if (mapMode === 'markers') { 885 var arr = window[$(this).data('json-markers-array')]; 886 887 $.each(arr, function (i, el) { 888 place.coords = el.coords.split(','); 889 890 if (typeof (el.marker_icon) !== 'undefined') { 891 place.marker_icon = el.marker_icon; 892 } 893 894 if (typeof (el.title) === 'string') { 895 place.title = el.title; 896 } 897 898 if (typeof (el.description) === 'string') { 899 place.description = el.description; 900 } 901 902 // add custom data to places, specific to in your area map 903 if (plugin.settings.in_your_area_map === true) { 904 if (typeof (el.category_code) === 'string') { 905 place.category_code = el.category_code; 906 } 907 908 if (typeof (el.marker_id) !== 'undefined') { 909 place.marker_id = el.marker_id; 910 } 911 912 if (typeof (el.overlay_content) !== 'undefined') { 913 place.overlay_content = el.overlay_content; 914 } 915 916 if (typeof (el.group) === 'string') { 917 place.group = el.group; 918 } 919 } 920 921 plugin.places[plugin.places_count] = jQuery.extend({}, place); 922 ++plugin.places_count; 923 }); 924 } 925 926 plugin.initMap(map); 927 928 }); 929 }, 930 931 findAddress: function (address, component_restriction) { 932 var plugin = this, 933 address = (address != undefined) ? address : $(plugin.settings.search.search_form + ' input').val(), 934 results_place = $(plugin.settings.search.search_results), 935 i, 936 place, 937 html, 938 you_icon, 939 request; 940 941 if (component_restriction === false && component_restriction !== undefined) { 942 // remove restriction as this will only be used with direct lat / long set by scottish water 943 request = { 944 address: address 945 }; 946 } else { 947 948 // pass country restriction on search terms via google api component restrictions 949 // limits search queries to the UK only 950 request = { 951 address: address, 952 componentRestrictions: { 953 country: 'UK' 954 } 955 }; 956 } 957 geocoder.geocode(request, function (results, status) { 958 959 var bounds = new google.maps.LatLngBounds(); 960 961 if (status === google.maps.GeocoderStatus.OK) { 962 963 if (typeof plugin.places.you !== 'undefined') { 964 plugin.places.you.setMap(null); 965 delete plugin.places.you; 966 } 967 968 you_icon = { 969 url: '/sites/scottishwater/images/svgs/map_markers/map-marker-you.svg', 970 scaledSize: new google.maps.Size(20, 27) 971 }; 972 973 plugin.places.you = new google.maps.Marker({ 974 position: results[0].geometry.location, 975 map: plugin.google_map, 976 icon: you_icon, 977 title: 'You', 978 address: results[0].formatted_address, 979 }); 980 981 var sorted_points = sortPointsByProximity(results[0].geometry.location, plugin.places, plugin.settings.search.distance), 982 nearest_point_key = getFirstKey(sorted_points); 983 //reset results 984 985 results_place.html(''); 986 987 $.each(plugin.places, function () { 988 this.marker.setVisible(false); 989 }); 990 991 //start bounds from search place 992 bounds.extend(plugin.places.you.getPosition()); 993 994 //if results then show 995 if (sorted_points.length > 0) { 996 997 // very specific grouping and list view markup for in your area map 998 if (plugin.settings.in_your_area_map === true) { 999 1000 // set up grouping for list items based on "group" json value being the same
1001 var grouped = [], 1002 inner_html; 1003 1004 for (var i in sorted_points) { 1005 if (i >= plugin.settings.search.max_results) { 1006 return false; 1007 }; 1008 1009 // make sorted points usable 1010 place = plugin.places[sorted_points[i].id]; 1011 1012 // push them to grouped variable 1013 grouped.push(place); 1014 } 1015 1016 // set up grouping, puts matching elements in same array, with "group" from json as key 1017 var final_groups = grouped.reduce(function (result, current) { 1018 result[current.group] = result[current.group] || []; 1019 result[current.group].push(current); 1020 return result; 1021 }, {}); 1022 1023 // loop through groups to generate appropriate markup for list 1024 $.each(final_groups, function (index, value) { 1025 // empty inner html to avoid duplicates 1026 inner_html = ''; 1027 1028 // loop through coords individually to get usable list elements 1029 $.each(value, function (i, data) { 1030 inner_html += '<li data-category-code="' + data.category_code + '"><a href="#" class="js_inYourAreaOverlay" data-no-ajax="true" data-marker-id="' + data.marker_id + '"><span class="areaMapIcon"><img src="' + data.marker_icon + '" alt="' + data.category_code + ' Icon"></span>' + data.overlay_content.overlay_title + ' <i class="fa fa-angle-right" aria-hidden="true"></i></a></li>'; 1031 1032 bounds.extend(data.marker.getPosition()); 1033 1034 //plugin.google_map.fitBounds(bounds); 1035 // Center and fit all bounds in view 1036 if (typeof plugin.places.you !== 'undefined') { 1037 plugin.google_map.setCenter(plugin.places.you.getPosition()); 1038 } 1039 plugin.google_map.setZoom(14); 1040 plugin.fitAllBounds(bounds); 1041 1042 data.marker.setVisible(true); 1043 }); 1044 1045 // build html from above loops 1046 html = '<div class="areaMapList js_areaMapList"><h2>' + index + '</h2><ul>' + inner_html + '</ul></div>'; 1047 1048 // append to page 1049 results_place.append(html); 1050 }); 1051 // Bound changed listener 1052 google.maps.event.addListenerOnce(plugin.google_map, 'bounds_changed', function () { 1053 var current_zoom = this.getZoom(); 1054 // Min zoom level when only 1 marker within radius 1055 if (grouped.length < 2) { 1056 this.setZoom(Math.min(8, current_zoom)); 1057 } 1058 }); 1059 1060 } else { 1061 // generic list view markup 1062 for (var i in sorted_points) { 1063 1064 if (i >= plugin.settings.search.max_results) { 1065 return false; 1066 }; 1067 1068 place = plugin.places[sorted_points[i].id]; 1069 1070 html = '<li><h3><a href="" data-map-id="' + plugin.map_id + '" data-place-id="' + sorted_points[i].id + '" class="js_focusMarker">' + place.title + ' <i class="fa fa-caret-right"></i></a></h3><div class="description">' + place.description + '</div></li>' 1071 1072 bounds.extend(place.marker.getPosition()); 1073 1074 plugin.google_map.fitBounds(bounds); 1075 1076 results_place.append(html); 1077 1078 place.marker.setVisible(true); 1079 1080 } 1081 } 1082 1083 if (plugin.settings.in_your_area_map === true) { 1084 $('.js_nothingInAreaText').remove(); 1085 $('.js_mapNothingFound').remove(); 1086 } 1087 1088 //show clear results button 1089 $('.js_clearMapResults').show(); 1090 1091 //if no results 1092 } else { 1093 plugin.google_map.setCenter(plugin.places.you.getPosition()); 1094 1095 if (component_restriction === false && component_restriction !== undefined) { 1096 // if initial value is being used (as no location or search done) then set zoom a little higher 1097 plugin.google_map.setZoom(7); 1098 } else { 1099 // else, just work as normal 1100 plugin.google_map.setZoom(plugin.settings.search.result_zoom); 1101 } 1102 if (plugin.settings.in_your_area_map === true) { 1103 if ($('.js_nothingInAreaText').length < 1) { 1104 $(plugin.settings.search.search_form).append(plugin.settings.search.no_results_markup); 1105 } 1106 results_place.html(plugin.settings.search.nothing_found_markup); 1107 $('.js_clearMapResults').hide(); 1108 } else { 1109 results_place.append(plugin.settings.search.no_results_markup); 1110 } 1111 } 1112 1113 // hide these 1114 $('.js_error').remove(); 1115 1116 if (plugin.settings.in_your_area_map === true) { 1117 // reset filter markers 1118 $('.js_mapLabel').removeClass('off'); 1119 $('.js_mapLabel .labelToggle').removeClass('off'); 1120 } 1121 1122 } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) { 1123 if ($('.js_error').length < 1) { 1124 $(plugin.settings.search.search_form).append('<p class="error js_error">Please enter a valid location.</p>'); 1125 $('.js_clearMapResults').hide(); 1126 } 1127 1128 if (plugin.settings.in_your_area_map === true) { 1129 $('.js_nothingInAreaText').remove(); 1130 } 1131 1132 if (plugin.settings.in_your_area_map === true) { 1133 // reset filter markers 1134 $('.js_mapLabel').removeClass('off'); 1135 $('.js_mapLabel .labelToggle').removeClass('off'); 1136 } 1137 1138 } else if (status === google.maps.GeocoderStatus.INVALID_REQUEST) { 1139 if ($('.js_error').length < 1) { 1140 $(plugin.settings.search.search_form).append('<p class="error js_error">Please enter your location.</p>'); 1141 $('.js_clearMapResults').hide(); 1142 } 1143 1144 if (plugin.settings.in_your_area_map === true) { 1145 $('.js_nothingInAreaText').remove(); 1146 } 1147 1148 if (plugin.settings.in_your_area_map === true) { 1149 // reset filter markers 1150 $('.js_mapLabel').removeClass('off'); 1151 $('.js_mapLabel .labelToggle').removeClass('off'); 1152 } 1153 1154 } 1155 }); 1156 return false; 1157 }, 1158 1159 setOptions: function (options) { 1160 var currentOptions = this.settings; 1161 this.settings = $.extend(true, {}, currentOptions, options); 1162 } 1163 } 1164}(jQuery, window, document));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.