1/* 2 ================================================== 3 Mobile menu - NEW VERSION 4 ================================================== 5*/ 6 7$(function () { 8 $("nav.nav-mobile ul.menu-collapse").on( 9 "click", 10 "li.has-children .icon", 11 function () { 12 if ($(this).hasClass("auto-open")) { 13 $(this).next("ul").slideToggle(true); 14 $(this).closest("li").toggleClass("active"); 15 return; 16 } 17 18 $(this).closest("li").toggleClass("active"); 19 20 let apiUrl = 21 "/Templates/Knowit/Pages/MobileNavigation.aspx?pageId=" + 22 $(this).attr("data-id"); 23 24 var myButton = $(this); 25 $.ajax({ 26 dataType: "json", 27 url: apiUrl, 28 success: function (json) { 29 var ul = myButton.next("ul"); 30 ul.html(""); 31 for (var i = 0; i < json.length; i++) { 32 var obj = json[i]; 33 34 var li = null; 35 36 if (obj.HasChildren) { 37 li = $("<li class='has-children'></li>"); 38 } else { 39 li = $("<li></li>"); 40 } 41 42 var a = $("<a href='" + obj.Url + "'>" + obj.Name + "</a>"); 43 var btn = $( 44 "<button type='button' data-id='" + 45 obj.Id + 46 "' class='icon'></button>" 47 ); 48 var newUl = $('<ul class="subnav"></ul >'); 49 50 li.append(a); 51 52 if (obj.HasChildren) { 53 li.append(btn); 54 li.append(newUl); 55 } 56 57 ul.append(li); 58 } 59 60 // Show the new menu list 61 myButton.next("ul").slideToggle(true); 62 myButton.toggleClass("expanded"); 63 }, 64 }); 65 } 66 ); 67}); 68 69/* 70 ================================================== 71 Mobile menu - OLD VERSION 72 ================================================== 73*/ 74 75$(function () { 76 $("nav.nav-mobile a.toggle-navigation-btn").on("click", (function (e) { 77 e.preventDefault(); 78 $("nav.nav-mobile ul.menu-collapse").slideToggle("slow"); 79 $("nav.nav-mobile a.toggle-navigation-btn").toggleClass("active"); 80 $("body").toggleClass("nav-active"); 81 })); 82 83 //toggle menu tabs 84 $(".menu-collapse li.menu-title").on("click", (function (e) { 85 if ($(this).hasClass("main-menu")) { 86 $(".menu-collapse li.menu-title").removeClass("active"); 87 $(".menu-collapse li.menu").removeClass("active"); 88 $(".menu-collapse").find(".main-menu").toggleClass("active", true); 89 } else if ($(this).hasClass("entry-links-menu")) { 90 $(".menu-collapse li.menu-title").removeClass("active"); 91 $(".menu-collapse li.menu").removeClass("active"); 92 $(".menu-collapse").find(".entry-links-menu").toggleClass("active", true); 93 } 94 })); 95 96 //expand sub-menu 97 $("nav.nav-mobile ul.menu-collapse li.active > .icon").each(function () { 98 $(this).next("ul").slideToggle(true); 99 }); 100}); 101 102/* 103 ================================================== 104 Navigation - Megamenu 105 ================================================== 106*/ 107$(function () { 108 // Fixed navigation 109 $(window).on("scroll", (function () { 110 if ($(this).scrollTop() > 159) 111 $('nav[role="navigation"]').addClass("fixed"); 112 else if ($('nav[role="navigation"]').hasClass("fixed")) 113 $('nav[role="navigation"]').removeClass("fixed"); 114 })); 115 116 // Hover 117 118 var timeOut; 119 var timeOutMilliseconds = 500; 120 var navigation = $('nav[role="navigation"] ul.nav'); 121 var megamenu = $('nav[role="navigation"] ul.nav .flyout'); 122 123 function open() { 124 return $(navigation).hasClass("open"); 125 } 126 127 function hasSubmenu(that) { 128 return $(that).children(".flyout").length != 0; 129 } 130 131 $('nav[role="navigation"] ul.nav > li').hover( 132 function () { 133 var me = this; 134 135 if (!open()) 136 timeOut = setTimeout(function () { 137 showMegameny(me); 138 }, timeOutMilliseconds); 139 else showMegameny(me); 140 }, 141 function () { 142 clearTimeout(timeOut); 143 $('nav[role="navigation"] ul.nav li').removeClass("focus"); 144 } 145 ); 146 147 function showMegameny(that) { 148 // Remove close class 149 if (!hasSubmenu(that) && open()) $(navigation).removeClass("open"); 150 151 // Close 152 if (open()) $(megamenu).hide(); 153 else $(megamenu).fadeOut(); 154 155 // Open 156 if (hasSubmenu(that)) { 157 $(that).addClass("focus"); 158 159 if (!open()) { 160 $(that).children(".flyout").stop(true, true).fadeIn(); 161 $(navigation).addClass("open"); 162 } else $(that).children(".flyout").show(); 163 } 164 } 165 166 $('nav[role="navigation"] ul.nav').on("mouseleave", function () { 167 // Closes megamenu when user moves cursor i the header 168 if (open()) { 169 $(megamenu).fadeOut(); 170 $(navigation).removeClass("open"); 171 172 $('nav[role="navigation"] ul.nav li').removeClass("focus"); 173 } 174 });
175 176 $(megamenu).on("mouseover", function (e) { 177 // Check if its not a derived container that is clicked 178 if ($(this).is(e.target) && $(this).has(e.target).length === 0) { 179 // Inactivate events once 180 $('nav[role="navigation"]').off("mouseleave"); 181 182 $(navigation).removeClass("open"); 183 $('nav[role="navigation"] ul.nav li').removeClass("focus"); 184 $(megamenu).fadeOut(); 185 } 186 }); 187}); 188 189/* 190 ================================================== 191 Toggle 192 ================================================== 193*/ 194 195$(function () { 196 //vars 197 var currentBlock = false; 198 var selectedBlock = false; 199 var allTabBlocks = $(".tabblock"); 200 201 //init 202 $(".toggle-content.block-1").addClass("show"); 203 204 //find all tabblocks and give them unique id's to prevent conflicts 205 $.each(allTabBlocks, function (i, block) { 206 $(block).addClass("toggle-" + i); 207 }); 208 209 //toggle on click 210 $(".tabblock nav a").on("click", (function (e) { 211 e.preventDefault(); 212 213 //Check if already selected 214 if (!$(this).parent().hasClass("focus")) { 215 //find parent to select the right box 216 currentBlock = 217 "." + $(this).closest(".tabblock").attr("class").replace(/ /g, "."); 218 219 //remove the currently visible content 220 $(currentBlock + " .toggle-content.show").removeClass("show"); 221 222 //find and show the newly selected content 223 selectedBlock = currentBlock + " .toggle-content." + this.className; 224 $(selectedBlock).addClass("show"); 225 226 //remove and assign nav indicator 227 $(currentBlock + " li.focus a") 228 .parent() 229 .removeClass("focus"); 230 $(this).parent().addClass("focus"); 231 } 232 })); 233}); 234 235 236/* 237 ================================================== 238 Slideshow 239 ================================================== 240 Requires cycle plugin and jquery 241*/ 242 243$(function () { 244 245 // Slideshow 246 $(".slideshow").each(function () { 247 // Init 248 var container = this; 249 var firstRun = true; 250 251 // Defaults for cycle plugin 252 var slideshowFx = "fade"; 253 var slideshowDelay = 0; 254 var slideshowTimeOut = 3000; 255 if (typeof globalSlideshowTimeOut != "undefined") { 256 slideshowTimeOut = globalSlideshowTimeOut; 257 } 258 259 var pauseByDefault = false; 260 261 262 // Controls 263 var slides = $(container).find(".slides"); // Div containing all slides 264 var next = $(container).find(".next"); // Next slide 265 var prev = $(container).find(".prev"); // Prev slide 266 var start = $(container).find(".start"); // Start slideshow 267 var stop = $(container).find(".stop"); // Stop slideshow 268 269 // Pager 270 var pager = $(container).find(".pager"); // Set to null if no pager 271 272 // Liveregion, used by screenreaders 273 var liveRegion = $(container).find(".liveregion"); 274 275 // Caption 276 var caption = ".caption"; // Classname of item containing the captiontext 277 var captionContainer = $(container).find(".caption-container"); // Caption display container 278 279 280 var totalSlides = $(slides).children("li").length; 281 282 // Check if there is more then one image 283 if ($(slides).children().length <= 1) { 284 // Hide all controls 285 $(start).hide(); 286 $(stop).hide(); 287 $(next).hide(); 288 $(prev).hide(); 289 $(pager).hide(); 290 291 // Show caption 292 var dataCaption = $(slides).children().children(caption).html(); 293 if (dataCaption != undefined) { 294 // Fade in caption if set 295 if (captionContainer.css("display") == "none") captionContainer.hide(); 296 297 $(captionContainer).html(dataCaption); 298 } else { 299 // Fade out caption if not set 300 captionContainer.hide(); 301 } 302 303 return 0; 304 } 305 306 // Cycle 307 $(slides).cycle({ 308 fx: slideshowFx, 309 delay: slideshowDelay, 310 timeout: slideshowTimeOut, 311 containerResize: true, 312 slideResize: true, 313 width: "100%", 314 fit: 1, 315 next: next, 316 prev: prev, 317 pager: pager, 318 before: function (curr, next, opts) { 319 // Liveregion 320 if (liveRegion !== undefined) { 321 var activeSlide = opts.nextSlide + 1; 322 if (firstRun) { 323 activeSlide = 1; 324 firstRun = false; 325 } 326 327 var liveRegionTextTemplate = window.slideshowStrings.liveRegionText; 328 329 liveRegionTextTemplate = liveRegionTextTemplate.replace( 330 "{0}", 331 activeSlide 332 ); 333 liveRegionTextTemplate = liveRegionTextTemplate.replace( 334 "{1}", 335 totalSlides 336 ); 337 338 $(liveRegion).text(liveRegionTextTemplate); 339 } 340 341 // Caption 342 var dataCaption = $(next).children(caption).html(); 343 if (dataCaption != undefined) { 344 // Fade in caption if set 345 if (captionContainer.css("display") == "none") 346 captionContainer.fadeIn(); 347 348 $(captionContainer).html(dataCaption); 349 } else { 350 // Fade out caption if not set 351 captionContainer.fadeOut(); 352 } 353 }, 354 pagerAnchorBuilder: function (idx, slide) { 355 var listItem = document.createElement("li"); 356 var button = document.createElement("button");
357 var pagerScreenReaderDesc = document.createElement("span"); 358 359 button.setAttribute("data-slide", idx); 360 button.setAttribute("aria-disabled", true); 361 button.setAttribute("tabindex", -1); 362 button.innerText = idx; 363 364 pagerScreenReaderDesc.classList.add("visuallyhidden"); 365 pagerScreenReaderDesc.innerText = window.slideshowStrings.pagerText; 366 367 button.appendChild(pagerScreenReaderDesc); 368 listItem.appendChild(button); 369 370 return listItem.outerHTML; 371 372 }, 373 }); 374 375 // Pause 376 if (pauseByDefault) { 377 $(slides).cycle("pause"); 378 HideControlElement(stop); 379 } else { 380 HideControlElement(start); 381 } 382 383 // Controls 384 $(start).on("click", (function (e) { 385 e.preventDefault(); 386 $(slides).cycle("resume"); 387 HideControlElement(start); 388 ShowControlElement(stop); 389 })); 390 391 $(stop).on("click", (function (e) { 392 e.preventDefault(); 393 $(slides).cycle("pause"); 394 HideControlElement(stop); 395 ShowControlElement(start); 396 })); 397 function HideControlElement(element) { 398 element.hide().attr("aria-hidden", "true"); 399 } 400 function ShowControlElement(element) { 401 element.show().attr("aria-hidden", "false"); 402 } 403 }); 404}); 405 406 407/* 408 ================================================== 409 Timeline 410 ================================================== 411*/ 412$(function () { 413 Array.prototype.slice.call(document.querySelectorAll('.TimelineBlock.AccordionContent .Accordion')).forEach(function (accordion) { 414 415 var allowMultiple = accordion.hasAttribute('data-allow-multiple'); 416 var allowToggle = (allowMultiple) ? allowMultiple : accordion.hasAttribute('data-allow-toggle'); 417 418 accordion.addEventListener('click', function (event) { 419 var target = event.target; 420 421 if (target.classList.contains('Accordion-trigger')) { 422 // Check if the current toggle is expanded. 423 var isExpanded = target.getAttribute('aria-expanded') == 'true'; 424 var panel = document.getElementById(target.getAttribute('aria-controls')); 425 target.classList.toggle('fa-plus'); 426 target.classList.toggle('fa-minus'); 427 428 $(panel).slideToggle('slow'); 429 430 if (!isExpanded) { 431 // Set the expanded state on the triggering element 432 target.setAttribute('aria-expanded', 'true'); 433 // Hide the accordion sections, using aria-controls to specify the desired section 434 document.getElementById(target.getAttribute('aria-controls')).removeAttribute('hidden'); 435 436 437 // If toggling is not allowed, set disabled state on trigger 438 if (!allowToggle) { 439 target.setAttribute('aria-disabled', 'true'); 440 } 441 } 442 else if (allowToggle && isExpanded) { 443 // Set the expanded state on the triggering element 444 target 445 target.setAttribute('aria-expanded', 'false'); 446 // Hide the accordion sections, using aria-controls to specify the desired section 447 document.getElementById(target.getAttribute('aria-controls')).setAttribute('hidden', ''); 448 } 449 450 } 451 }); 452 }); 453}); 454 455/* 456 ================================================== 457 Project Filter - Tabs + Accordion 458 ================================================== 459*/ 460$(function () { 461 if ($(".project-filter").length) { 462 if ($(".project-filter").hasClass("project-google-map")) { 463 $(this).find(".filter-menu").accordion(); 464 465 $(window).on("load resize", function () { 466 if (window.innerWidth > 992) { 467 $(".project-google-map").find(".filter-menu").accordion("destroy"); 468 } else { 469 $(".project-google-map").find(".filter-menu").accordion({ 470 heightStyle: "content", 471 collapsible: true, 472 clearStyle: true, 473 active: 0, 474 }); 475 } 476 }); 477 } else { 478 $(this).find(".filter-menu").tabs(); 479 } 480 } 481}); 482 483/* 484 ================================================== 485 Files list - Area 486 ================================================== 487*/ 488$(function () { 489 if ($("#accordion").length) { 490 $("#accordion").accordion({ 491 heightStyle: "content", 492 collapsible: true, 493 clearStyle: true, 494 active: currentActive, 495 }); 496 } 497}); 498 499$(function () { 500 if ($("#accordion-billboard").length) { 501 $("#accordion-billboard").accordion({ 502 heightStyle: "content", 503 collapsible: true, 504 clearStyle: true, 505 active: false, 506 }); 507 } 508}); 509 510/* 511 ================================================== 512 Contact - Area 513 ================================================== 514*/ 515$(document).ready(function () { 516 $(".btn-contact").on("click", (function (e) { 517 e.preventDefault(); 518 $(".ContactArea").slideToggle(); 519 $(".btn-contact").toggleClass("close"); 520 })); 521 522 $(".contactcard-area").each(function (index) { 523 $(this).children().first().wrapInner("<strong></strong>"); 524 });
525}); 526 527/* 528 ================================================== 529 Contact form 530 ================================================== 531*/ 532 533$(document).ready(function () { 534 $(".ContactFormDDL").on("change", function (e) { 535 var i = $("option:selected", this).index(); 536 $(this).parent().find(".how-to-contact").hide().eq(i).show(); 537 e.preventDefault(); 538 }); 539 540 function checkToggle(id) { 541 if (id == "fileToggleBtn") { 542 var toggleVal = $(".txtToggleUpload").val(); 543 544 if ($(".txtToggleUpload").val() == "show") { 545 $(".txtToggleUpload").val("hide"); 546 } else { 547 $(".txtToggleUpload").val("show"); 548 } 549 } else if (id == "mapToggleBtn") { 550 var toggleMapVal = $(".txtToggleMap").val(); 551 552 if ($(".txtToggleMap").val() == "show") { 553 $(".txtToggleMap").val("hide"); 554 } else { 555 $(".txtToggleMap").val("show"); 556 } 557 } 558 } 559 560 $(".pull-down-button").on("click", (function (e) { 561 $(this).toggleClass("expanded"); 562 563 var callbackMethod = $(this).hasClass("expanded") ? "on-open" : "on-close"; 564 565 var callback = eval(jQuery(e.currentTarget).data(callbackMethod)); 566 567 $(this) 568 .siblings(".pull-down-container") 569 .first() 570 .slideToggle({ 571 duration: 500, 572 done: function () { 573 if (typeof callback == "function") { 574 callback(); 575 } 576 }, 577 }); 578 579 checkToggle(this.id); 580 581 e.preventDefault(); 582 })); 583 584 if ( 585 $(".txtToggleUpload").val() == "show" || 586 $(".txtToggleUpload").val() == "formerror" 587 ) { 588 $("#fileToggleBtn").toggleClass("expanded"); 589 590 $("#fileToggleBtn").siblings(".pull-down-container").first().slideToggle({ 591 duration: 500, 592 }); 593 } 594 if ( 595 $(".txtToggleMap").val() == "show" || 596 $(".txtToggleMap").val() == "formerror" 597 ) { 598 $("#mapToggleBtn").toggleClass("expanded"); 599 600 $("#mapToggleBtn") 601 .siblings(".pull-down-container") 602 .first() 603 .slideToggle({ 604 duration: 500, 605 complete: function () { 606 InitializeGoogleMaps(); 607 }, 608 }); 609 } 610}); 611 612/* 613 ================================================== 614 Project map filtering 615 ================================================== 616*/ 617 618var map; // Contains the google map object 619var coordinates = []; // Result from JSON request 620var markers = []; // Google map markers wrapped in a custom object 621var zoomLevel = 1; 622 623function createMapIcon(color, size) { 624 return { 625 //path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0", 626 path: google.maps.SymbolPath.CIRCLE, 627 fillColor: color, 628 fillOpacity: 1, 629 anchor: new google.maps.Point(0, 0), 630 strokeWeight: 4, 631 strokeColor: "#ffffff", 632 strokeOpacity: 1, 633 scale: size, 634 }; 635} 636 637function createCategoryList(jsonObj) { 638 var result = ""; 639 640 for (var i = 0; i < jsonObj.length; i++) { 641 result += 642 "<li>" + 643 '<span class="color-category" style="background:' + 644 jsonObj[i]["Color"] + 645 '"></span>' + 646 "</li>"; 647 } 648 649 return result; 650} 651 652function initMap() { 653 map = new google.maps.Map(document.getElementById("project-google-map"), { 654 center: { lat: 58.3917535, lng: 13.8437657 }, 655 zoom: 10, 656 disableDefaultUI: true, 657 }); 658 659 google.maps.event.addListener(map, "zoom_changed", function () { 660 var i, prevZoomLevel; 661 662 prevZoomLevel = zoomLevel; 663 664 map.getZoom() < 16 ? (zoomLevel = 1) : (zoomLevel = 2); 665 666 if (prevZoomLevel !== zoomLevel) { 667 for (i = 0; i < markers.length; i++) { 668 if (zoomLevel === 2) { 669 markers[i].marker.setIcon(markers[i].bigIcon); 670 } else { 671 markers[i].marker.setIcon(markers[i].defaultIcon); 672 } 673 } 674 } 675 });
676 677 var xhr = new XMLHttpRequest(); 678 xhr.open("GET", projectMapSettings.coordinatesServiceUrl); 679 xhr.onload = function () { 680 if (xhr.status === 200) { 681 var jsonResult = JSON.parse(xhr.responseText); 682 coordinates = jsonResult; // Save for filtering 683 684 var infowindow = new google.maps.InfoWindow(); /* SINGLE */ 685 for (var i = 0; i < jsonResult.length; i++) { 686 var color = jsonResult[i]["ColorizedCategories"][0]["Color"]; 687 688 var contentString = 689 '<div id="content">' + 690 '<div id="siteNotice">' + 691 "</div>" + 692 '<h1 id="firstHeading" class="firstHeading"><a href="' + 693 jsonResult[i]["Link"] + 694 '">' + 695 jsonResult[i]["Heading"] + 696 "</a></h1>" + 697 '<div class="project-categories"><span class="subheading">Kategorier</span><ul>' + 698 createCategoryList(jsonResult[i]["ColorizedCategories"]) + 699 "</ul></div>" + 700 '<div id="bodyContent" class="project-map-status"><p>' + 701 jsonResult[i]["Status"] + 702 "</p>" + 703 "</div>" + 704 "</div>"; 705 706 var icon = createMapIcon(color, 9); 707 var bigIcon = createMapIcon(color, 13); 708 709 var marker = new google.maps.Marker({ 710 position: new google.maps.LatLng( 711 jsonResult[i]["Latitude"], 712 jsonResult[i]["Longitude"] 713 ), 714 icon: icon, 715 map: map, 716 info: contentString, 717 }); 718 719 google.maps.event.addListener(marker, "click", function () { 720 infowindow.setContent(this.info); 721 infowindow.open(map, this); 722 }); 723 724 var wrapper = { 725 marker: marker, 726 categories: jsonResult[i]["ProjectCategories"], 727 defaultIcon: icon, 728 bigIcon: bigIcon, 729 }; 730 731 markers.push(wrapper); 732 } 733 } else { 734 console.log("Request failed. Returned status of " + xhr.status); 735 } 736 }; 737 xhr.send(); 738} 739 740 741let polygonData = []; 742let GlobalOngoingMap; 743function initProjectMap(zoomLevelValue, startCoordinates, catId = null) { 744 GlobalOngoingMap = new google.maps.Map(document.getElementById('project-locations-google-map'), { 745 center: { lat: Number(startCoordinates[0]), lng: Number(startCoordinates[1]) }, 746 zoom: zoomLevelValue, 747 disableDefaultUI: true, 748 }); 749 750 //Fixes a array with coordinates from string 751 let htmlCollection = document.getElementsByClassName("maps-data"); 752 let allMapData = Array.prototype.slice.call(htmlCollection); 753 754 755 allMapData.forEach(data => { 756 let coordinates = []; 757 let tempCoordinates = data.dataset.coordinates.replaceAll(/\s/g, '').split(";"); 758 tempCoordinates.forEach(locatinoCoord => { 759 let location = locatinoCoord.split(","); 760 if (Number(location[0]) > 0 && Number(location[1]) > 0) { 761 let coordinateObj = { lat: Number(location[0]), lng: Number(location[1]) } 762 coordinates.push(coordinateObj); 763 } 764 }); 765 766 //changes opacity if there is a selected filter 767 let opacity = 0.35; 768 if (data.dataset.category == catId && catId != null) { 769 opacity = 0.8 770 } 771 772 //pushes data to polygonData array to keep when recreating polygons 773 polygonData.push({ 774 cords: coordinates, 775 color: data.dataset.color, 776 opacity: opacity, 777 width: 2, 778 indexId: data.dataset.category 779 }) 780 }); 781 createMapPolygons(polygonData, GlobalOngoingMap); 782} 783 784let lastShownId = ""; 785//Holds map polygons so they can be removed 786let mapPolygons = []; 787function createMapPolygons(polygonObjecArray, map) { 788 //Adds the polygons to the map 789 polygonObjecArray.forEach(item => { 790 let x = new google.maps.Polygon({ 791 paths: item.cords, 792 strokeColor: item.color, 793 strokeOpacity: item.opacity, 794 strokeWeight: item.width, 795 fillColor: item.color, 796 fillOpacity: item.opacity, 797 indexID: item.indexId 798 }); 799 mapPolygons.push(x);
800 x.setMap(map); 801 802 //Adds event listener to recreate polygons with the right opacity and display the right content 803 google.maps.event.addListener(x, 'click', function (event) { 804 const statusBar = document.getElementById(x.indexID + "-statusbar"); 805 const lastStatusBar = document.getElementById(lastShownId + "-statusbar"); 806 const elem = document.getElementById(x.indexID); 807 const selectedFilterButtons = document.querySelectorAll('a[data-id="' + x.indexID + '"]'); 808 const lastSelectedFilterButtons = document.querySelectorAll('a[data-id="' + x.indexID + '"]'); 809 const url = new URL(window.location); 810 811 812 //displays the right content based on id 813 if (lastShownId == "") { 814 document.getElementById("start-article").classList.add("hidden"); 815 document.getElementById("start-wideBlock").classList.add("hidden"); 816 if (document.getElementById("startpage-statusbar") != null) { 817 document.getElementById("startpage-statusbar").classList.add("hidden"); 818 } 819 window.history.pushState({}, '', window.location.origin + window.location.pathname); 820 } 821 if (elem != undefined) { 822 elem.classList.remove("hidden"); 823 selectedFilterButtons.forEach(selectedButton => { 824 selectedButton.classList.add("active"); 825 }) 826 if (statusBar != null) { 827 statusBar.classList.remove("hidden"); 828 } 829 url.searchParams.set('category', x.indexID); 830 window.history.pushState({}, '', url); 831 832 if (lastShownId != "" && x.indexID != lastShownId) { 833 document.getElementById(lastShownId).classList.add("hidden"); 834 lastSelectedFilterButtons.forEach(lastSelectedButton => { 835 lastSelectedButton.classList.add("active"); 836 }) 837 if (lastStatusBar != null) { 838 lastStatusBar.classList.add("hidden"); 839 } 840 } 841 if (x.indexID == lastShownId) { 842 elem.classList.add("hidden"); 843 lastSelectedFilterButtons.forEach(lastSelectedButton => { 844 lastSelectedButton.classList.add("active"); 845 }) 846 if (lastStatusBar != null) { 847 lastStatusBar.classList.add("hidden"); 848 } 849 document.getElementById("start-article").classList.remove("hidden"); 850 document.getElementById("start-wideBlock").classList.remove("hidden"); 851 if (document.getElementById("startpage-statusbar") != null) { 852 document.getElementById("startpage-statusbar").classList.remove("hidden"); 853 } 854 window.history.pushState({}, '', window.location.origin + window.location.pathname); 855 } 856 removeLastActiveFilterStyle(); 857 } 858 859 //removes active polygons and add less opacity to selected polygon then create new polygons 860 let newPolygons = []; 861 for (i in mapPolygons) { 862 let temp = []; 863 if (polygonData[i].indexId == x.indexID && lastShownId != x.indexID) { 864 temp = polygonData[i]; 865 temp.opacity = 0.8; 866 newPolygons.push(temp); 867 } else { 868 temp = polygonData[i]; 869 temp.opacity = 0.35; 870 newPolygons.push(temp); 871 } 872 mapPolygons[i].setMap(null); 873 } 874 mapPolygons = []; 875 if (lastShownId == x.indexID) { 876 lastShownId = ""; 877 } else { 878 lastShownId = x.indexID; 879 } 880 createMapPolygons(newPolygons, map) 881 }); 882 });
883} 884 885$(document).ready(function () { 886 let projectLocationMap = document.getElementById("project-locations-google-map"); 887 if (projectLocationMap != undefined) { 888 let zoomLevelValue = document.getElementById("map-props").dataset.zoomlevel; 889 let startCoordinates = document.getElementById("map-props").dataset.startcoord; 890 startCoordinates = startCoordinates.replaceAll(/\s/g, ''); 891 startCoordinates = startCoordinates.split(','); 892 893 //Get filter category id 894 let params = (new URL(document.location)).searchParams; 895 let catId = params.get('category'); 896 let statusBar = document.getElementById(catId + "-statusbar"); 897 898 initProjectMap(Number(zoomLevelValue), startCoordinates, catId); 899 900 if (catId != null || catId != undefined) { 901 lastShownId = catId 902 document.getElementById("start-article").classList.add("hidden"); 903 document.getElementById("start-wideBlock").classList.add("hidden"); 904 if (document.getElementById("startpage-statusbar") != null) { 905 document.getElementById("startpage-statusbar").classList.add("hidden"); 906 } 907 document.getElementById(catId).classList.remove("hidden"); 908 document.querySelector('a[data-id="' + lastShownId + '"]').classList.add("active"); 909 if (statusBar != null) { 910 statusBar.classList.remove("hidden"); 911 } 912 } 913 914 const resetFilters = document.querySelectorAll(".reset-ongoing-filter"); 915 resetFilters.forEach(resetFilter => { 916 resetFilter.addEventListener("click", function (e) { 917 e.preventDefault(); 918 statusBar = document.getElementById(lastShownId + "-statusbar"); 919 //Push url to history 920 const url = new URL(window.location.origin + window.location.pathname); 921 window.history.pushState({}, '', url); 922 923 let descriptions = Array.prototype.slice.call(document.getElementsByClassName("project-description")); 924 descriptions.forEach(descriptionElement => { 925 if (!descriptionElement.classList.contains("hidden")) { 926 descriptionElement.classList.add("hidden"); 927 if (statusBar != null) { 928 statusBar.classList.add("hidden"); 929 } 930 } 931 }) 932 document.getElementById("start-article").classList.remove("hidden"); 933 document.getElementById("start-wideBlock").classList.remove("hidden"); 934 if (document.getElementById("startpage-statusbar") != null) { 935 document.getElementById("startpage-statusbar").classList.remove("hidden"); 936 } 937 938 removeLastActiveFilterStyle(); 939 940 for (i in mapPolygons) { 941 polygonData[i].opacity = 0.35; 942 mapPolygons[i].setMap(null); 943 } 944 mapPolygons = []; 945 lastShownId = ""; 946 createMapPolygons(polygonData, GlobalOngoingMap) 947 }) 948 }) 949 950 document.querySelector(".projects-map-filter.project-filter #ui-id-1").addEventListener("click", function (e) { 951 if (window.outerWidth < 992) { 952 toggleFilterMenuOnGoingProjects(e.target); 953 } 954 }) 955 } 956}) 957 958function toggleFilterMenuOnGoingProjects(target) { 959 if (!target.classList.contains("open")) { 960 target.classList.add("open"); 961 document.querySelector(".projects-map-filter.project-filter .filter-menu-links").classList.add("open"); 962 document.querySelector(".projects-map-filter.project-filter .ui-tabs-panel.ui-corner-bottom.ui-widget-content").ariaHidden = true; 963 } else { 964 target.classList.remove("open"); 965 document.querySelector(".projects-map-filter.project-filter .filter-menu-links").classList.remove("open"); 966 document.querySelector(".projects-map-filter.project-filter .ui-tabs-panel.ui-corner-bottom.ui-widget-content").ariaHidden = false; 967 } 968} 969 970// let lastActiveFilterId = null; 971function activateFilter(e) { 972 e.preventDefault();
973 let categoryId = e.target.dataset.id; 974 975 if (lastShownId == categoryId) { 976 return; 977 } 978 979 //show/hide content areas and text 980 if (categoryId != null) { 981 const url = new URL(window.location); 982 const statusBar = document.getElementById(categoryId + "-statusbar"); 983 const lastStautsBar = document.getElementById(lastShownId + "-statusbar"); 984 url.searchParams.set('category', categoryId); 985 window.history.pushState({}, '', url); 986 987 let descriptions = Array.prototype.slice.call(document.getElementsByClassName("project-description")); 988 descriptions.forEach(descriptionElement => { 989 if (descriptionElement.id == categoryId) { 990 if (descriptionElement.classList.contains("hidden")) { 991 document.getElementById("start-article").classList.add("hidden"); 992 document.getElementById("start-wideBlock").classList.add("hidden"); 993 if (document.getElementById("startpage-statusbar") != null) { 994 document.getElementById("startpage-statusbar").classList.add("hidden"); 995 } 996 descriptionElement.classList.remove("hidden"); 997 if (lastStautsBar != null) { 998 lastStautsBar.classList.add("hidden"); 999 } 1000 var filterButtons = document.querySelectorAll('a[data-id="' + e.target.dataset.id + '"]'); 1001 filterButtons.forEach((button) => { 1002 if (!button.classList.contains("active")) { 1003 button.classList.add("active"); 1004 } 1005 }) 1006 1007 removeLastActiveFilterStyle(); 1008 1009 lastShownId = descriptionElement.id 1010 } 1011 } else { 1012 descriptionElement.classList.add("hidden"); 1013 if (statusBar != null) { 1014 statusBar.classList.remove("hidden"); 1015 } 1016 } 1017 }) 1018 //removes active polygons and add less opacity to selected polygon then create new polygons 1019 let newPolygons = []; 1020 for (i in mapPolygons) { 1021 let temp = []; 1022 if (polygonData[i].indexId == categoryId) { 1023 temp = polygonData[i]; 1024 temp.opacity = 0.8; 1025 newPolygons.push(temp); 1026 } else { 1027 temp = polygonData[i]; 1028 temp.opacity = 0.35; 1029 newPolygons.push(temp); 1030 } 1031 mapPolygons[i].setMap(null); 1032 } 1033 mapPolygons = []; 1034 createMapPolygons(newPolygons, GlobalOngoingMap) 1035 } else { 1036 document.getElementById("start-article").classList.remove("hidden"); 1037 document.getElementById("start-wideBlock").classList.remove("hidden"); 1038 if (document.getElementById("startpage-statusbar") != null) { 1039 document.getElementById("startpage-statusbar").classList.remove("hidden"); 1040 } 1041 } 1042} 1043 1044function removeLastActiveFilterStyle() { 1045 if (lastShownId != "") { 1046 let prevElem = document.querySelectorAll('a[data-id="' + lastShownId + '"]'); 1047 prevElem.forEach((element) => { 1048 if (element.classList.contains("active")) { 1049 element.classList.remove("active"); 1050 } 1051 }) 1052 } 1053} 1054 1055$(function () { 1056 if (googleMapsIsEnabled()) { 1057 initMap(); 1058 } 1059}); 1060 1061var defaultColor = "#CCCCCC"; 1062var hoverColor = "rgba(205, 230, 141,1)"; 1063var selectedColor = "#B9E600"; 1064 1065// string.format (override) 1066if (!String.prototype.format) { 1067 String.prototype.format = function () { 1068 var args = arguments; 1069 return this.replace(/{(\d+)}/g, function (match, number) { 1070 return typeof args[number] != "undefined" ? args[number] : match; 1071 }); 1072 }; 1073} 1074 1075function googleMapsIsEnabled() { 1076 return ( 1077 typeof projectMapSettings !== "undefined" && 1078 projectMapSettings.showGoogleMap && 1079 projectMapSettings.coordinatesServiceUrl !== "" 1080 ); 1081} 1082 1083function filterListBySelector(selector) { 1084 $(".list-projects-block .list-item") 1085 .addClass("hidden-project") 1086 .filter(selector) 1087 .removeClass("hidden-project"); 1088} 1089 1090function setListingHeader(text) { 1091 $("#project-listing-header").html( 1092 text + 1093 " <span class='list-projects-count'>" + 1094 $(".list-projects-block .list-item:not(.hidden-project)").length + 1095 "</span>" 1096 ); 1097} 1098 1099function clearMapStyle() { 1100 // Clear color style 1101 var mapItems = document.getElementsByClassName("map-item"); 1102 for (var i = 0; i < mapItems.length; i++) { 1103 removeClass(mapItems[i], "map-item-selected"); 1104 mapItems[i].setAttribute("style", "fill:'" + defaultColor + "' "); 1105 } 1106 1107 // Clear labels 1108 $(".projects-map-graphic .text:visible").hide(); 1109} 1110 1111function colorMapElements(id, color) { 1112 $(".projects-map-graphic .filter-cat-" + id) 1113 .get() 1114 .forEach(function (element) { 1115 if (!hasClass(element, "map-item-selected")) { 1116 $(element).css({ fill: color }); 1117 $(element).next(".text").toggle(); 1118 } 1119 }); 1120} 1121 1122function colorMapElement(mapElement, color) { 1123 if (!hasClass(mapElement, "map-item-selected")) { 1124 mapElement.css({ fill: color }); 1125 } 1126} 1127 1128function colorMapSubElements(subElementsArr, color) { 1129 subElementsArr.forEach(function (element) { 1130 if (!!hasClass(element, "map-item-selected")) { 1131 $(element).css({ fill: color }); 1132 } 1133 });
1134} 1135 1136function munListHover(hoverElement, color, cursor) { 1137 var mapElement = $( 1138 ".projects-map-graphic #" + hoverElement.parent().attr("data-name") 1139 ); 1140 1141 // Mariestad consists of several paths 1142 if (mapElement.attr("id") == "Mariestad") { 1143 colorMapSubElements(mapElement.find(".map-item").get(), color); 1144 mapElement.find(".map-item").css("cursor", cursor); 1145 if (!hasClass(mapElement.find(".map-item").first(), "map-item-selected")) { 1146 mapElement.find(".text").toggle(); 1147 } 1148 } else { 1149 if (!hasClass(mapElement, "map-item-selected")) { 1150 mapElement.next(".text").toggle(); 1151 } 1152 colorMapElement(mapElement, color); 1153 mapElement.css("cursor", cursor); 1154 } 1155} 1156 1157function mapHover(hoverElement, color, cursor, show) { 1158 if ($(hoverElement).attr("id").indexOf("Mariestad") > -1) { 1159 var subElements = $(hoverElement).siblings("path"); 1160 if (!hasClass(hoverElement, "map-item-selected")) { 1161 $(hoverElement).css({ fill: color }); 1162 subElements.css({ fill: color }); 1163 $(hoverElement).parent(".map-group").find(".text").toggle(); 1164 } 1165 subElements.css("cursor", cursor); 1166 } else if (!hasClass(hoverElement, "map-item-selected")) { 1167 $(hoverElement).css({ fill: color }); 1168 $(hoverElement).next(".text").toggle(); 1169 } 1170 $(hoverElement).css("cursor", cursor); 1171} 1172 1173function clearFilter() { 1174 $(".filter-menu-links a").removeClass("filter-menu-selected"); 1175} 1176 1177/* IE 11 hack functions */ 1178 1179function addClass(element, cssClass) { 1180 if (element.length) 1181 element.attr("class", element.attr("class") + " " + cssClass); 1182 else $(element).attr("class", $(element).attr("class") + " " + cssClass); 1183} 1184 1185function hasClass(element, cssClass) { 1186 if (element.length) return element.attr("class").indexOf(cssClass) >= 0; 1187 else return $(element).attr("class").indexOf(cssClass) >= 0; 1188} 1189 1190function removeClass(element, cssClass) { 1191 if (element.length) 1192 return element.attr("class", element.attr("class").replace(cssClass, "")); 1193 else 1194 return $(element).attr( 1195 "class", 1196 $(element).attr("class").replace(cssClass, "") 1197 ); 1198} 1199 1200function getParameterByName(name, url) { 1201 if (!url) { 1202 url = window.location.href; 1203 } 1204 1205 name = name.replace(/[\[\]]/g, "\\$&"); 1206 var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), 1207 results = regex.exec(url); 1208 if (!results) return null; 1209 if (!results[2]) return ""; 1210 return decodeURIComponent(results[2].replace(/\+/g, " ")); 1211} 1212 1213function setParameter(name, value) { 1214 var re = new RegExp("([?&])" + name + "=.*?(&|$)", "i"); 1215 var search = window.location.search; 1216 var hash = window.location.hash; 1217 var separator = search.indexOf("?") !== -1 ? "&" : "?"; 1218 1219 if (search.match(re)) { 1220 search = search.replace( 1221 re, 1222 "$1" + name + "=" + encodeURIComponent(value) + "$2" 1223 ); 1224 } else { 1225 search = search + separator + name + "=" + encodeURIComponent(value); 1226 } 1227 1228 history.replaceState(null, null, search + hash); 1229} 1230 1231$(function () { 1232 function setSelected(elem) { 1233 setParameter("cat", elem.data("id")); 1234 let selectedTab = elem.closest("div").attr("id"); 1235 1236 if (selectedTab.length) { 1237 setParameter("t", selectedTab); 1238 } else { 1239 setParameter("t", ""); 1240 } 1241 } 1242 1243 // MUNICIPALITIES LIST - CLICK 1244 $(".municipalities-filter a").on("click", function (e) { 1245 e.preventDefault(); 1246 1247 var li = $(this).parent(); 1248 var id = li.attr("data-id"); 1249 var name = li.attr("data-name"); 1250 1251 setSelected(li); 1252 1253 $(".filter-menu-links a").removeClass("filter-menu-selected"); 1254 $(this).addClass("filter-menu-selected"); 1255 1256 filterListBySelector(".filter-mun-" + id); 1257 1258 setListingHeader(listingHeadingFormat.format("i " + name)); 1259 1260 clearMapStyle(); 1261 1262 var mapElement = $( 1263 ".projects-map-graphic #" + $(this).parent().attr("data-name") 1264 ); 1265 1266 // Mariestad constist of several paths 1267 if (mapElement.attr("id") == "Mariestad") { 1268 var subElements = mapElement.find(".map-item"); 1269 subElements.css({ fill: selectedColor }); 1270 mapElement.find(".text").toggle(); 1271
1272 subElements.get().forEach(function (element) { 1273 addClass(element, "map-item-selected"); 1274 }); 1275 } else { 1276 mapElement.css({ fill: selectedColor }); 1277 addClass(mapElement, "map-item-selected"); 1278 mapElement.next(".text").toggle(); 1279 } 1280 }); 1281 1282 // CATEGORY LIST - CLICK 1283 $(".categories-filter a").on("click", function (e) { 1284 e.preventDefault(); 1285 1286 var li = $(this).parent(); 1287 var id = li.attr("data-id"); 1288 var name = li.attr("data-name"); 1289 1290 setSelected(li); 1291 1292 $(".filter-menu-links a").removeClass("filter-menu-selected"); 1293 $(this).addClass("filter-menu-selected"); 1294 1295 filterListBySelector(".filter-cat-" + id); 1296 setListingHeader(listingHeadingFormat.format("inom " + name)); 1297 1298 clearMapStyle(); 1299 1300 $(".projects-map-graphic .filter-cat-" + id) 1301 .get() 1302 .forEach(function (element) { 1303 $(element).css({ fill: selectedColor }); 1304 addClass(element, "map-item-selected"); 1305 $(element).next(".text").toggle(); 1306 }); 1307 1308 if (googleMapsIsEnabled()) { 1309 // Google map filter 1310 map.getZoom() < 16 ? (zoomLevel = 1) : (zoomLevel = 2); 1311 var catId = parseInt(id); 1312 for (var i = 0; i < markers.length; i++) { 1313 if (!markers[i].categories.includes(catId)) { 1314 markers[i].marker.setVisible(false); 1315 } else { 1316 markers[i].marker.setIcon(null); 1317 1318 if (zoomLevel === 2) { 1319 markers[i].marker.setIcon(markers[i].bigIcon); 1320 } else { 1321 markers[i].marker.setIcon(markers[i].defaultIcon); 1322 } 1323 1324 markers[i].marker.setVisible(true); 1325 } 1326 } 1327 1328 google.maps.event.trigger(map, "resize"); 1329 } 1330 }); 1331 1332 // MUNICIPALITIES LIST - HOVER 1333 $(".municipalities-filter a").hover( 1334 // ON HOVER ENTER 1335 function () { 1336 munListHover($(this), hoverColor, "pointer"); 1337 }, 1338 1339 // ON HOVER LEAVE 1340 function () { 1341 munListHover($(this), defaultColor, "default"); 1342 } 1343 ); 1344 1345 // CATEGORIES LIST - HOVER 1346 $(".categories-filter a").hover( 1347 // ON HOVER ENTER 1348 function () { 1349 colorMapElements($(this).parent().attr("data-id"), hoverColor); 1350 }, 1351 1352 // ON HOVER LEAVE 1353 function () { 1354 colorMapElements($(this).parent().attr("data-id"), defaultColor); 1355 } 1356 ); 1357 1358 // MAP - HOVER 1359 $(".projects-map-graphic .map-item").hover( 1360 // ON HOVER ENTER 1361 function () { 1362 mapHover(this, hoverColor, "pointer", true); 1363 }, 1364 // ON HOVER LEAVE 1365 function () { 1366 mapHover(this, defaultColor, "default", false); 1367 } 1368 ); 1369 1370 // MAP - CLICK 1371 $(".projects-map-graphic .map-item").on("click", function (e) { 1372 e.preventDefault(); 1373 1374 clearMapStyle(); 1375 1376 var name = $(this).attr("id"); // Name of the municipality 1377 1378 // Mariestad hack 1379 if (name.indexOf("Mariestad") > -1) { 1380 name = "Mariestad"; 1381 } 1382 1383 var municipalityItem = $( 1384 ".municipalities-filter " + "li[data-name='" + name + "']" 1385 ).find("a"); 1386 1387 if (municipalityItem.length > 0) municipalityItem.click(); // Lazy me 1388 }); 1389 1390 // MUNICIPALITIES (MOBILE) - ON CHANGE 1391 $("#municipalities-filter-mobile").on("change", function () { 1392 var id = $("#municipalities-filter-mobile option") 1393 .filter(":selected") 1394 .val(); 1395 var name = $("#municipalities-filter-mobile option") 1396 .filter(":selected") 1397 .text(); 1398 1399 if (id == "-1") { 1400 $("#categories-filter-mobile").val("-1"); 1401 $("#municipalities-filter-mobile").val("-1"); 1402 filterListBySelector(".list-item"); 1403 setListingHeader(listingHeadingFormat.format("i Skaraborg "));
1404 return; 1405 } 1406 1407 $("#categories-filter-mobile").val("-1"); 1408 1409 filterListBySelector(".filter-mun-" + id); 1410 setListingHeader(listingHeadingFormat.format("i " + name)); 1411 }); 1412 1413 // CATEGORIES (MOBILE) - ON CHANGE 1414 $("#categories-filter-mobile").on("change", function () { 1415 var id = $("#categories-filter-mobile option").filter(":selected").val(); 1416 var name = $("#categories-filter-mobile option").filter(":selected").text(); 1417 1418 if (id == "-1") { 1419 $("#categories-filter-mobile").val("-1"); 1420 $("#municipalities-filter-mobile").val("-1"); 1421 filterListBySelector(".list-item"); 1422 setListingHeader(listingHeadingFormat.format("i Skaraborg ")); 1423 return; 1424 } 1425 1426 $("#municipalities-filter-mobile").val("-1"); 1427 1428 filterListBySelector(".filter-cat-" + id); 1429 setListingHeader(listingHeadingFormat.format("inom " + name)); 1430 }); 1431 1432 // FILTER ALL - CLICK 1433 $(".reset-filter").on("click", function (e) { 1434 e.preventDefault(); 1435 1436 setParameter("cat", ""); 1437 setParameter("t", ""); 1438 1439 // Desktop 1440 clearMapStyle(); 1441 clearFilter(); 1442 filterListBySelector(".list-item"); 1443 setListingHeader( 1444 listingHeadingFormat.format(projectMapSettings.listingHeadingDefaultText) 1445 ); 1446 1447 // Mobile 1448 $("#categories-filter-mobile").val("-1"); 1449 $("#municipalities-filter-mobile").val("-1"); 1450 1451 if (googleMapsIsEnabled()) { 1452 // Google map 1453 for (var i = 0; i < markers.length; i++) { 1454 markers[i].marker.setVisible(true); 1455 markers[i].marker.setIcon(markers[i].defaultIcon); 1456 } 1457 } 1458 }); 1459 1460 let filterId = getParameterByName("cat"); 1461 if (filterId) { 1462 let activeTab = getParameterByName("t"); 1463 if (activeTab.length) { 1464 if (activeTab === "tabs-1") { 1465 $("#categories-filter-mobile").val(filterId); 1466 $("#municipalities-filter-mobile").val("-1"); 1467 } else if (activeTab === "tabs-2") { 1468 $("#municipalities-filter-mobile").val(filterId); 1469 $("#categories-filter-mobile").val("-1"); 1470 } 1471 1472 $("a[href=#" + activeTab + "]").trigger( "click"); 1473 } 1474 1475 let li = $("li[data-id=" + filterId + "]"); 1476 let filterLink = li.children("a"); 1477 if (!filterLink.length) { 1478 return; 1479 } 1480 1481 if (googleMapsIsEnabled()) { 1482 google.maps.event.addListenerOnce(map, "idle", function () { 1483 filterLink.trigger("click"); 1484 }); 1485 } else { 1486 filterLink.trigger("click"); 1487 } 1488 } 1489 1490 /* 1491 ================================================== 1492 Datepicker 1493 ================================================== 1494 */ 1495 var dayNamesShort = ["Mån", "Tis", "Ons", "Tors", "Fre", "Lör", "Sön"]; 1496 var monthNames = [ 1497 "Januari", 1498 "Februari", 1499 "Mars", 1500 "April", 1501 "Maj", 1502 "Juni", 1503 "Juli", 1504 "Augusti", 1505 "September", 1506 "Oktober", 1507 "November", 1508 "December", 1509 ]; 1510 function format(dt) { 1511 return ( 1512 Picker.prototype.pad(dt.getDate()) + 1513 " " + 1514 monthNames[dt.getMonth()].slice(0, 3) + 1515 " " + 1516 dt.getFullYear() 1517 ); 1518 } 1519 1520 var datepicker = function (root) { 1521 "use strict"; 1522 1523 var icon = 1524 '<svg viewBox="0 0 512 512"><polygon points="268.395,256 134.559,121.521 206.422,50 411.441,256 206.422,462 134.559,390.477 "/></svg>'; 1525 var dateInput = $(root).siblings("#date")[0]; 1526 var altInput = $(root).siblings("#alt")[0]; 1527 var calendarBlock = $(root).closest(".EventCalendarBlock")[0]; 1528 1529 var doc = document.documentElement; 1530 1531 function show() { 1532 root.removeAttribute("hidden"); 1533 } 1534 1535 function hide() { 1536 root.setAttribute("hidden", ""); 1537 doc.removeEventListener("click", hide); 1538 } 1539 1540 function onSelectHandler() { 1541 var value = this.get(); 1542 if (value.start) { 1543 dateInput.value = value.start.Ymd(); 1544 altInput.value = format(value.start); 1545 hide(); 1546 1547 var e = document.createEvent("HTMLEvents"); 1548 e.initEvent("oninput", false, true); 1549 calendarBlock.dispatchEvent(e); 1550 } 1551 } 1552 1553 var picker = new Picker(root, { 1554 min: new Date(dateInput.min), 1555 max: new Date(dateInput.max), 1556 icon: icon, 1557 twoCalendars: false, 1558 dayNamesShort: dayNamesShort, 1559 monthNames: monthNames, 1560 onSelect: onSelectHandler, 1561 }); 1562 1563 root.parentElement.addEventListener("click", function (e) { 1564 e.stopPropagation(); 1565 }); 1566 1567 dateInput.addEventListener("change", function () { 1568 if (dateInput.value) { 1569 picker.select(new Date(dateInput.value)); 1570 } else { 1571 picker.clear(); 1572 } 1573 }); 1574 1575 altInput.addEventListener("focus", function () { 1576 altInput.blur(); 1577 show(); 1578 doc.addEventListener("click", hide, false); 1579 }); 1580 return picker; 1581 }; 1582 1583 //CalendarTileBlock Functions 1584 1585 //CalendarBlock Functions 1586 1587 var jsonPostObjectTemplate = { 1588 IncludeContent: true, 1589 SearchTypes: "Event", 1590 Skip: 0, 1591 Site: 5428, 1592 Sort: "Date", 1593 }; 1594 1595 var months = [ 1596 "Jan", 1597 "Feb", 1598 "Mar", 1599 "Apr", 1600 "Maj", 1601 "Jun", 1602 "Jul", 1603 "Aug", 1604 "Sep", 1605 "Okt", 1606 "Nov", 1607 "Dec", 1608 ]; 1609 1610 $(".calendar-tile-block").each(function (index) { 1611 var element = $(this); 1612 var loadingElement = element.find(".calendar-loader"); 1613 var eventsContainer = element.find(".events"); 1614 var jsonPostObject = jsonPostObjectTemplate; 1615 var take = element.data("take");
1616 var openInDetailsPage = element.data("detailpage"); 1617 var detailsPageUrl = element.data("detailspageurl"); 1618 1619 var baseUrl = element.data("baseurl"); 1620 var eventRoute = element.data("route"); 1621 1622 loadingElement.toggle(); 1623 1624 jsonPostObject.Take = take; 1625 1626 if (element.data("tags") !== "") { 1627 jsonPostObject.Tags = element.data("tags"); 1628 } 1629 if (element.data("config") !== "") { 1630 jsonPostObject.Settings = element.data("config"); 1631 } 1632 jsonPostObject.Date = new Date(); 1633 1634 $.ajax({ 1635 url: baseUrl + eventRoute, 1636 data: jsonPostObject, 1637 dataType: "json", 1638 method: "Post", 1639 success: function (response) { 1640 var result = ""; 1641 1642 response.Hits.forEach(function (hit) { 1643 var startDate = new Date(hit.Start); 1644 var endDate = new Date(hit.End); 1645 var dateString = ""; 1646 1647 if ((startDate.getDay() && startDate.getMonth()) != (endDate.getDay() && endDate.getMonth())) { 1648 if (startDate.getMonth() != endDate.getMonth()) { 1649 dateString = startDate.getDate() + ' ' + months[startDate.getMonth()] + ' - ' + endDate.getDate() + ' ' + months[endDate.getMonth()]; 1650 } else { 1651 dateString = startDate.getDate() + ' - ' + endDate.getDate() + ' ' + months[endDate.getMonth()]; 1652 } 1653 } else { 1654 dateString = startDate.getDate() + ' ' + months[startDate.getMonth()]; 1655 } 1656 1657 var linkUrl = ""; 1658 if (openInDetailsPage === "true" || openInDetailsPage === "True") { 1659 linkUrl = detailsPageUrl + "?event=" + hit.Id; 1660 } else { 1661 linkUrl = baseUrl + hit.Url; 1662 } 1663 1664 result += [ 1665 '<a href="' + linkUrl + '" class="event">', 1666 '<div class="date">' + 1667 dateString + 1668 '</div>', 1669 '<div class="event-heading"><span>' + hit.Heading + "</span></div>", 1670 "</a>", 1671 ].join("\n"); 1672 }); 1673 loadingElement.toggle(); 1674 eventsContainer.append(result); 1675 }, 1676 }); 1677 }); 1678 1679 $(".EventCalendarBlock").each(function (index) { 1680 var element = $(this); 1681 var datepickerelem = element.find("#picker"); 1682 1683 var picker; 1684 if (datepickerelem) { 1685 picker = datepicker(datepickerelem[0]); 1686 if (picker) { 1687 picker.set(new Date()); 1688 picker.select(new Date()); 1689 } 1690 } 1691 1692 var calendarHeader = element.find(".EventCalendarHeader"); 1693 var calendarFooter = element.find(".EventCalendarFooter"); 1694 var calendarFilter = element.find(".EventCalendarFilter"); 1695 var calendarList = element.find(".EventCalendarList"); 1696 var loadingElement = element.find(".calendar-loader"); 1697 1698 var startDateElement = calendarHeader.find(".start-date"); 1699 1700 var showMore = calendarFooter.find("#calendar-next-page"); 1701 1702 var searchButton = calendarFilter.find(".button"); 1703 1704 var clearFilters = calendarHeader.find(".clear-filters"); 1705 var totalHitsElement = calendarHeader.find(".total-hits"); 1706 var totalShowingElement = calendarHeader.find(".showing"); 1707 var showingQuery = calendarHeader.find(".query"); 1708 1709 var loadingClass = "calender-loading"; 1710 1711 var jsonPostObject = jsonPostObjectTemplate; 1712 var take = element.data("take"); 1713 1714 jsonPostObject.Take = take; 1715 1716 if (element.data("tags") !== "") { 1717 jsonPostObject.Tags = element.data("tags"); 1718 } 1719 if (element.data("config") !== "") { 1720 jsonPostObject.Settings = element.data("config"); 1721 } 1722 1723 jsonPostObject.ImageSize = { Crop: true, height: 400, width: 400 }; 1724 1725 var readMoreTranslation = element.data("readmore"); 1726 var searchField = element.find("#calendar-search"); 1727 var baseUrl = element.data("baseurl"); 1728 var eventRoute = element.data("route");
1729 var openInDetailsPage = element.data("detailpage"); 1730 var detailsPageUrl = element.data("detailspageurl"); 1731 1732 var toggleLoadingState = function () { 1733 calendarList.toggleClass(loadingClass); 1734 loadingElement.toggle(); 1735 }; 1736 1737 var sendRequest = function () { 1738 toggleLoadingState(); 1739 if (searchField.val() && searchField.val().length > 0) { 1740 jsonPostObject.Query = searchField.val(); 1741 } else { 1742 jsonPostObject.Query = ""; 1743 } 1744 showingQuery.html(jsonPostObject.Query); 1745 var tempDate = null; 1746 if (picker.get().start) { 1747 tempDate = new Date(picker.get().start); 1748 jsonPostObject.Date = tempDate.toISOString(); 1749 jsonPostObject.DayRange = 365; 1750 startDateElement.html(format(tempDate)); 1751 } else { 1752 tempDate = new Date(new Date()); 1753 jsonPostObject.Date = tempDate.toISOString(); 1754 jsonPostObject.DayRange = 365; 1755 startDateElement.html(format(tempDate)); 1756 } 1757 1758 $.ajax({
1759 url: baseUrl + eventRoute, 1760 data: jsonPostObject, 1761 dataType: "json", 1762 method: "Post", 1763 success: function (response) { 1764 var result = ""; 1765 totalHitsElement.text(response.TotalCount); 1766 totalShowingElement.text(response.Hits.length); 1767 response.Hits.forEach(function (hit) { 1768 var tmpDescElement = document.createElement("DIV"); 1769 tmpDescElement.innerHTML = hit.Description; 1770 var desc = 1771 tmpDescElement.textContent || tmpDescElement.innerText || ""; 1772 1773 if (desc.length > 200) { 1774 desc = desc.slice(0, 200); 1775 desc += "..."; 1776 } 1777 1778 var startDate = new Date(hit.Start); 1779 var endDate = new Date(hit.End); 1780 var today = new Date(jsonPostObject.Date); 1781 var date = startDate >= today ? startDate : today; 1782 var endDate = new Date(hit.End); 1783 1784 hit.Dates = hit.Dates.filter(function (d) { 1785 return new Date(d.Date) >= today; 1786 }).sort(function (a, b) { 1787 return new Date(a.Date) - new Date(b.Date); 1788 }); 1789 1790 if (hit.Dates[0] != undefined) { 1791 date = new Date(hit.Dates[0].Date); 1792 } 1793 1794 var formattedDate = formatDate(date); 1795 var startAndEndDate = ""; 1796 if ((startDate.getDate() && startDate.getMonth()) == (endDate.getDate() && endDate.getMonth())) { 1797 startAndEndDate += [ 1798 '<div class="only-start-date">' + 1799 '<div class="start-date">' + 1800 '<span class="day">' + 1801 startDate.getDate() + 1802 '</span>' + 1803 '<span class="month">' + 1804 months[endDate.getMonth()] + 1805 '</span>' + 1806 '</div>' + 1807 '</div>', 1808 ]; 1809 } else { 1810 startAndEndDate += [ 1811 '<div class="start-end-date">' + 1812 '<div class="start-date">' + 1813 '<span class="day">' + 1814 startDate.getDate() + 1815 '</span>' + 1816 '<span class="month">' + 1817 months[startDate.getMonth()] + 1818 '</span>' + 1819 '</div>' + 1820 '<span class="hyphen">-</span>' + 1821 '<div class="end-date">' + 1822 '<span class="day">' + 1823 endDate.getDate() + 1824 '</span>' + 1825 '<span class="month">' + 1826 months[endDate.getMonth()] + 1827 '</span>' + 1828 '</div>' + 1829 '</div>' 1830 ]; 1831 } 1832 1833 var linkTo = "" 1834 if (openInDetailsPage === "true" || openInDetailsPage === "True") { 1835 linkTo += ['<a href="' + detailsPageUrl + '?event=' + hit.Id + '" class="external-link">' + 1836 '<span class="internal-link">' + readMoreTranslation + "</span>" + 1837 "</a>"] 1838 } else { 1839 linkTo += ['<a href="' + baseUrl + hit.Url + '" class="external-link">' + 1840 "<span>" + readMoreTranslation + "</span>" + 1841 '<i class="fas fa-external-link-alt"></i>' + 1842 "</a>"] 1843 } 1844 1845 result += [ 1846 '<div class="EventCalendarItem">', 1847 '<div class="inner">', 1848 '<div class="image">', 1849 '<img alt="' + 1850 hit.Heading + 1851 '" title="' + 1852 hit.Heading + 1853 '" src="' + 1854 hit.Image.Path + 1855 '">', 1856 startAndEndDate + 1857 '</div >', 1858 '<div class="text">', 1859 '<div class="date">' + formattedDate + "</div>", 1860 '<h3 class="heading">' + hit.Heading + "</h3>", 1861 '<p class="intro">' + desc + "</p>", 1862 '<div class="actions">' + 1863 linkTo + 1864 "</div>", 1865 "</div >", 1866 "</div >", 1867 "</div>", 1868 ].join("\n"); 1869 }); 1870 if (response.Hits.length === response.TotalCount) { 1871 showMore.hide(); 1872 } else { 1873 showMore.show(); 1874 } 1875 calendarList.append(result); 1876 toggleLoadingState(); 1877 }, 1878 }); 1879 }; 1880 var submit = function (e) { 1881 if (e !== undefined) { 1882 if (e.keyCode === 13) { 1883 e.stopPropagation(); 1884 e.preventDefault(); 1885 calendarList.html(""); 1886 jsonPostObject.Skip = 0; 1887 sendRequest(); 1888 } else if (e.keyCode === undefined) { 1889 calendarList.html(""); 1890 jsonPostObject.Skip = 0; 1891 sendRequest(); 1892 } 1893 } else { 1894 calendarList.html(""); 1895 jsonPostObject.Skip = 0; 1896 sendRequest(); 1897 } 1898 }; 1899 1900 clearFilters.on("click", function (e) { 1901 calendarList.html(""); 1902 jsonPostObject.Skip = 0; 1903 searchField.val(""); 1904 jsonPostObject.Date = new Date(); 1905 picker.select(jsonPostObject.Date); 1906 picker.set(jsonPostObject.Date); 1907 sendRequest(); 1908 }); 1909 showMore.on("click", function (e) { 1910 jsonPostObject.Skip += jsonPostObject.Take; 1911 sendRequest(); 1912 }); 1913 1914 searchField.on("keydown", submit); 1915 element.on("oninput", submit); 1916 searchButton.on("click", submit); 1917 sendRequest(); 1918 });
1919 1920 function formatDate(date) { 1921 var d = new Date(date), 1922 month = "" + (d.getMonth() + 1), 1923 day = "" + d.getDate(), 1924 year = d.getFullYear(); 1925 1926 if (month.length < 2) month = "0" + month; 1927 if (day.length < 2) day = "0" + day; 1928 1929 return [year, month, day].join("-"); 1930 } 1931}); 1932 1933/* Search Page */ 1934$(document).ready(function () { 1935 if ($("#normalResult").length > 0) { 1936 if ($(self.window).width() <= 479) { //use antoher icon in mobile mode 1937 $("[rel='next']").empty().html("»") 1938 $("[rel='prev']").empty().html("«") 1939 } 1940 else { 1941 $("[rel='next']").empty().html("Nästa »") 1942 $("[rel='prev']").empty().html("« Föregående") 1943 } 1944 1945 $("[rel='next']").add("[rel='prev']").addClass("customesspaging") 1946 1947 $("[rel='next']").add("[rel='prev']").hover( 1948 function () { 1949 $(this).css("background-color", "#E50052"); 1950 $(this).css("color", "#FFF"); 1951 }, function () { 1952 $(this).css("background-color", ""); //to remove property set it to '' 1953 $(this).css("color", "#000"); 1954 } 1955 ); 1956 } 1957}); 1958 1959/*Cookiebot event handlers*/ 1960$(function () { 1961 window.addEventListener('CookiebotOnAccept', function (e) { 1962 if (Cookiebot.consent.statistics) { 1963 $vizzit.cookie.set(); 1964 } 1965 }, false); 1966}); 1967 1968/* Rek ai autocomplete */ 1969$(function () { 1970 var scriptTag = document.querySelector('script[src="https://static.rekai.se/addon/rekai_autocomplete.min.js"]'); 1971 if (scriptTag != null) { 1972 var rekAutocomplete = rekai_autocomplete('.SearchTfd', { 1973 clearOnSelected: true, 1974 styled: true, 1975 highlight: true, 1976 }, 1977 [{ 1978 templates: { 1979 suggestion: function (suggestion, dataset) { 1980 // If news article 1981 if (suggestion.url.indexOf('http') == 0) { 1982 var boldText = highlightWord(suggestion.title, dataset); 1983 return '<p class="search-page-normal"><a href="' + suggestion.url + '"><span>' + boldText + '</span></a></p>';; 1984 } 1985 else { // Else render normaly 1986 var boldText = highlightWord(suggestion.title, dataset); 1987 return '<p class="search-page-normal">' + boldText + '</p>'; 1988 } 1989 } 1990 } 1991 }] 1992 ).on('rekai_autocomplete:selected', function (event, suggestion, dataset) { 1993 if (suggestion.url.indexOf('http') == 0) { 1994 window.location = suggestion.url; 1995 } 1996 window.location = '/Sokresultat?query=' + encodeURIComponent(suggestion.title); 1997 }).on('rekai_autocomplete:updated ', function (event) { 1998 var dropdownMenus = document.querySelectorAll(".rekai-dropdown-menu"); 1999 dropdownMenus.forEach(function (Menu) { 2000 Menu.style.width = Math.round(document.body.clientWidth * 0.15) + "px" 2001 }) 2002 }); 2003 } 2004}) 2005function highlightWord(text, query) { 2006 // Create a case-insensitive regular expression 2007 let regex = new RegExp(`(${query})`, 'gi'); 2008 // Replace the matching text with bold text 2009 return text.replace(regex, '<b>$1</b>'); 2010} 2011 2012/* FacilityOpenHours block */ 2013$(document).ready(function () { 2014 $('.facility-opening-hours .previous-week').on('click', (e) => { 2015 e.preventDefault(); 2016 var targetContainer = $(e.target).closest('.facility-opening-hours'); 2017 if ($(targetContainer).find('.next-week').hasClass('hidden')) { 2018 $(targetContainer).find('.next-week').removeClass('hidden'); 2019 } 2020 var elements = $(targetContainer).find('.week-day-list').get().reverse(); 2021 var startElement = -1; 2022 var endElement = -1; 2023 for (var i = 0; i < elements.length; i++) { 2024 if (!$(elements[i]).hasClass('hidden')) { 2025 $(elements[i]).addClass('hidden'); 2026 $(elements[i]).removeClass('active'); 2027 2028 if (startElement === -1) { 2029 startElement = i + 7; 2030 endElement = startElement + 6; 2031 } 2032 } 2033 2034 if (i >= startElement && i <= endElement) { 2035 $(elements[i]).removeClass('hidden'); 2036 $(elements[i]).addClass('active'); 2037 } 2038 } 2039 2040 if (startElement === (elements.length - 7)) { 2041 $(targetContainer).find('.previous-week').addClass('hidden'); 2042 return 2043 } 2044 }) 2045 2046 $('.facility-opening-hours .next-week').on('click', (e) => { 2047 e.preventDefault(); 2048 var targetContainer = $(e.target).closest('.facility-opening-hours'); 2049 if ($(targetContainer).find('.previous-week').hasClass('hidden')) { 2050 $(targetContainer).find('.previous-week').removeClass('hidden'); 2051 } 2052 2053 var elements = $(targetContainer).find('.week-day-list'); 2054 var startElement = -1; 2055 var endElement = -1; 2056 var x = 1; 2057 for (var i = 0; i < elements.length; i++) { 2058 2059 if (!$(elements[i]).hasClass('hidden')) { 2060 $(elements[i]).addClass('hidden'); 2061 $(elements[i]).removeClass('active'); 2062 if (startElement === -1) { 2063 startElement = i + 7; 2064 endElement = startElement + 6; 2065 } 2066 } 2067 2068 if (i >= startElement && i <= endElement) { 2069 $(elements[i]).removeClass('hidden'); 2070 $(elements[i]).addClass('active'+ x +''); 2071 x++; 2072 } 2073 } 2074 2075 if ( endElement === (elements.length - 1)) { 2076 $(targetContainer).find('.next-week').addClass('hidden'); 2077 return 2078 } 2079 }) 2080 2081}); 2082 2083/* Accordion trigger */ 2084$(document).ready(function () { 2085 if ($(".Accordion-trigger").length > 0) 2086 { 2087 $(".Accordion-trigger").on('click', function (e) { 2088 if ($(e.target).attr("aria-expanded") == "false") { 2089 $(e.target).parent().find(".accordion-extenstion").addClass("expanded"); 2090 2091 } else { 2092 setTimeout(() => { 2093 $(e.target).parent().find(".accordion-extenstion").delay(1500).removeClass("expanded") 2094 }, 2095 599); 2096 } 2097 }) 2098 } 2099});
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.