window.csrfToken = 'dSXc1rj5be'; // Functions that are not core, but common to multiple widgets function hasJquery() { return 'undefined' !== typeof window.jQuery; } function setupValidation(input) { $(input).parent().parent().addClass('was-validated'); } function validateTextarea(textarea) { var regexMsg = $(textarea).attr('data-regex'); var errorMsg = $(textarea).attr('data-message'); var pattern = new RegExp('^' + $(textarea).attr('pattern') + '$'); // check each line of text $.each($(textarea).val().split("\n"), function () { // check if the line matches the pattern var hasError = !this.match(pattern); if (hasError) { $(textarea).next().text(regexMsg); } else { $(textarea).next().text(errorMsg); } if (typeof textarea.setCustomValidity === 'function') { textarea.setCustomValidity(hasError ? errorMsg : ''); } else { // Not supported by the browser, fallback to manual error display... $(textarea).toggleClass('error', !!hasError); $(textarea).toggleClass('ok', !hasError); if (hasError) { $(textarea).attr('title', errorMsg); } else { $(textarea).removeAttr('title'); } } return !hasError; }); } function isInViewport($elem) { if ($elem.offset()) { var elementTop = $elem.offset().top; var elementBottom = elementTop + $elem.outerHeight(); var viewportTop = $(window).scrollTop(); var viewportBottom = viewportTop + $(window).height(); return elementBottom > viewportTop && elementTop < viewportBottom; } else { return false; } } //cms has col-sm-6 this has changed in bootstrap, so hotfix $(document).ready(function () { $('.col-xs-6').removeClass('col-xs-6').addClass('col-6'); }); if (!window.widgets) { window.widgets = {}; } window.widgets.allSetupSiteUi = function () { for (var key in this) { var widget = this[key]; if (typeof widget === 'object' && widget.setupSiteUi) { widget.setupSiteUi(); } } } function buildWidget(widgetType, args) { var constructor = window.widgets[widgetType.toLowerCase()].init; function F() { return constructor.apply(this, args); } F.prototype = constructor.prototype; return new F(); } function widget(elem) { var $widgetElem = $(elem); while (!$widgetElem.is('[data-widget-id],[data-widget-non-interactive-start]')) { $widgetElem = $widgetElem.parent(); if ($widgetElem.length === 0) { return null; // No widget found } } var widgetId = $widgetElem.attr('data-widget-id'); var widgetType = $widgetElem.attr('data-widget-type'); var widgetInstance = buildWidget(widgetType, [widgetId, $widgetElem]); var widgetBaseFunctionality = { id: widgetId, type: widgetType, element: $widgetElem, call: function (method, args, callback, cacheClientSide) { var widget = this; var url = '/widgetResources.axd?widgetCall=' + widgetId; if (!cacheClientSide) { url += '&rnd=' + Math.random(); } $.ajax({ url: window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + url, type: "POST", data: 'token=' + window.csrfToken + '&method=' + method + '&pageData=' + encodeURIComponent(JSON.stringify(getPageData($widgetElem))) + '&data=' + encodeURIComponent(JSON.stringify(args)), success: function (data, status, xhr) { callback(widget, data, status, xhr); }, error: function (xhr, status, err) { callback(widget, err, status, xhr); } }); } }; return $.extend(widgetInstance, widgetBaseFunctionality); } function getPageData($elem) { while ($elem.length) { if ($elem.attr('data-pageData')) { return JSON.parse($elem.attr('data-pageData')); } $elem = $elem.parent(); } } function setupModalEventListeners() { $('#add-to-cart-modal').on('shown.bs.modal', function (event) { var button = $(event.relatedTarget); var itemId = button.data('id'); var cartModalBody = $('#cart-modal-body'); if (cartModalBody) { cartModalBody.html(''); } var returnUrl = window.location.pathname + window.location.search; $.ajax({ url: '/ecomdata/getaddtocartmodal', type: 'GET', data: { treeId: itemId, returnUrl: returnUrl }, success: function (data) { cartModalBody.html(data); SetUpAddToCartForm(); $.validator.unobtrusive.parse('#add-to-cart-form'); SetUpCustomValidation(); }, error: function () { cartModalBody.html('

Error loading content. Please try again.

'); } }); }); } /*stock scroller*/ $(function () { if ($('.stock-slider').length) { const mql = window.matchMedia('(max-width: 767px)'); mql.addEventListener('change', onModeChange); onModeChange(mql); } }); function onModeChange(e) { if (e.matches) { // we’re now < 768px destroyDesktop(); initMobile(); } else { // we’re now ≥ 768px destroyMobile(); initDesktop(); } } function imageRotate(button) { $stockSlider = $(button).parent().parent().parent(); var $previousItem = $stockSlider.find(".custom-scroller .scroll-item[data-order=0]"); var $activeItem = $stockSlider.find(".custom-scroller .scroll-item[data-order=1]"); var $nextItem = $stockSlider.find(".custom-scroller .scroll-item[data-order=2]"); $stockSlider.find(".custom-scroller > div > div").each(function (index) { var newIndex = index - 1; if (newIndex == -1) { newIndex = 5; } $(this).attr('data-order', newIndex); if (newIndex == 1) { $(this).addClass('active'); } else { $(this).removeClass('active'); } }); $stockSlider.find(".custom-scroller > div").append(function () { return $(this).children().sort(function (a, b) { return $(a).attr("data-order") - $(b).attr("data-order"); }) }) scrollImages($stockSlider); } function scrollImages(stockSlider) { if ($(window).width() < 768) { var $previousItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=0]"); $previousItem.css({ "z-index": "0", "display": "none" }).animate({ left: 0, top: 0 }, 600, 'swing'); var $activeItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=1]"); $activeItem.css({ "z-index": "1", "display": "block" }).animate({ left: 0, top: 0 }, 600, 'swing'); var $nextItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=2]"); $nextItem.css({ "z-index": "0", "display": "none" }).animate({ left: 0, top: 0 }, 600, 'swing'); var $4Item = $(stockSlider).find(".custom-scroller .scroll-item[data-order=3]"); $4Item.css({ "z-index": "0", "display": "none" }).animate({ left: 0, top: 0 }, 600, 'swing'); var $5Item = $(stockSlider).find(".custom-scroller .scroll-item[data-order=4]"); $5Item.css({ left: $(window).width(), "z-index": 0, "display": "none" }); $(stockSlider).find('.scroll-item').removeClass('active'); $activeItem.addClass('active'); } else { var $previousItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=0]"); $previousItem.css("z-index", "0").animate({ left: -86, top: 200, width: 100, height: 100 }, 600, 'swing'); var $previousItemImage = $($previousItem).find("img"); $previousItemImage.css("z-index", "0") var $activeItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=1]"); $activeItem.css("z-index", "5").animate({ left: 50, top: 0, width: 300, height: 300 }, 600, 'swing'); var $activeItemImage = $($activeItem).find("img"); $activeItemImage.css("z-index", "5") var $nextItem = $(stockSlider).find(".custom-scroller .scroll-item[data-order=2]"); $nextItem.css("z-index", "4").animate({ left: 390, top: 200, width: 100, height: 100 }, 600, 'swing'); var $nextItemImage = $($nextItem).find("img"); $nextItemImage.css("z-index", "4") var $4Item = $(stockSlider).find(".custom-scroller .scroll-item[data-order=3]"); $4Item.css("z-index", "3").animate({ left: 530 }, 600, 'swing'); var $4ItemImage = $($4Item).find("img"); $4ItemImage.css("z-index", "3") var $5Item = $(stockSlider).find(".custom-scroller .scroll-item[data-order=4]"); $5Item.css("z-index", "2").css({ left: 660 }); var $5ItemImage = $($5Item).find("img"); $5ItemImage.css("z-index", "2") $(stockSlider).find('.scroll-item').removeClass('active'); $activeItem.addClass('active'); } } let mobileItems, mobileCurrentIndex; function initMobile() { $('.stock-slider').each(function (index, element) { mobileItems = $(element).find('.scroll-item'); mobileCurrentIndex = mobileItems.filter('.active').index(); // hide them all, show the one: mobileItems.hide() .eq(mobileCurrentIndex) .show() .addClass('active'); }); } function destroyMobile() { // clear out any fade/hidden state $('.stock-slider .scroll-item') .stop(true, true) .removeAttr('style') .removeClass('active') .show(); } function showSlide(newIndex) { newIndex = (newIndex + mobileItems.length) % mobileItems.length; mobileItems.eq(mobileCurrentIndex) .removeClass('active') .fadeOut(250); mobileItems.eq(newIndex) .addClass('active') .fadeIn(250); mobileCurrentIndex = newIndex; } function initDesktop() { $('.stock-slider').each(function (index, element) { // reset everything from mobile $(element).find('.scroll-item') .stop(true, true) .removeAttr('style') .removeClass('active') .show(); // then do your three-panel animation scrollImages($(element)); }); } function destroyDesktop() { // if your desktop ever bound swipeLeft/swipeRight, // clean it here—but really it just needs to look like “before initDesktop()” $('.stock-slider .scroll-item') .stop(true, true) .removeAttr('style') .removeClass('active') .show(); } if (!window.widgets) { window.widgets = {}; } window.widgets.assetdownloadform = { init: function (args) { return { submitForm: function () { if (typeof (validateChildNodes) != 'undefined') { // This might not be used so check if present if (!validateChildNodes(this.element)) { return; // Invalid } } this.origButtonText = $('#AssetDownloadForm_' + this.id + '_lnkSubmit').val(); $('#AssetDownloadForm_' + this.id + '_lnkSubmit').val('Please wait...').attr('disabled', true); var data = {}; var $questions = this.element.find(':input[id*=Question]'); // Even though "none" questions dont have any inputs we still need to iterate through them or i will be wrong for (var i = 0; i < $questions.length; i++) { var $question = $($questions[i]); if (typeof ($question.length && $question[0].checkValidity) == 'function') { if (!$question[0].checkValidity()) { $question.css({ outline: 'solid 2px #f00' }).addClass('invalid'); $question.blur(function () { $(this).css({ outline: 'none' }).removeClass('invalid'); }); $question[0].focus(); $('#AssetDownloadForm_' + this.id + '_lnkSubmit').val(this.origButtonText).removeAttr('disabled'); return; } } if ($question.is(':checkbox,:radio')) { data[$question.attr('data')] = $question.is(':checked'); } else { data[$question.attr('name')] = $question.val(); } } this.call('submitForm', data, this.gotResult); }, gotResult: function (widget, data, status) { $('#AssetDownloadForm_' + this.id + '_lnkSubmit').val(this.origButtonText).removeAttr('disabled'); if (status != 'success') { alert('An error occurred please try again.\n'); } else { widget.element.empty(); widget.element.append($('
').html(data.result)); } } }; } }; if (!window.widgets) { window.widgets = {}; } window.widgets.componentPopup = { init: function () { }, createCookie: function (name, value, days) { var expires; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toGMTString(); } else { expires = ""; } document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/"; }, readCookie: function (name) { var nameEQ = encodeURIComponent(name) + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length)); } return null; }, setupSiteUi: function () { if (hasJquery()) { $('.component-popup').each(function () { var $elem = $(this); if ($elem.data('is-setup')) { return; } $elem.data('is-setup', true); var id = $elem.attr("data-id"); var cookieName = 'component-popup-close-' + id; $elem.find('.component-popup-close').click(function () { window.widgets.componentPopup.createCookie(cookieName, id, 10000); $elem.modal('hide'); }); //open the popup if (window.widgets.componentPopup.readCookie(cookieName) != id) { $elem.modal('show'); } }); } } } window.widgets.componentPopup.setupSiteUi(); hasJquery && $(document).ready(window.widgets.componentPopup.setupSiteUi); /*Scrolling Widget*/ if ('undefined' == typeof window.jQuery) { } else { window.onload = function () { $(document).ready(function () { if ($('.componentticker .ticker-wrapper').length) { $('.componentticker .contentblock > div').each(function (index) { $(this).wrapInner('
'); }); $('.componentticker .ticker-wrapper').mouseenter(function () { $(this).addClass('hovered'); }).mouseleave(function () { $(this).removeClass('hovered'); }); $('.componentticker .ticker-wrapper').each(function (i) { $(this).attr("data-index", "1").attr("data-count", "0"); var dataId = $(this).parent().parent().attr("data-widget-id"); $(this).find(".btn-right").click(function () { componentSlide(dataId, "left", true) }); $(this).find(".btn-left").click(function () { componentSlide(dataId, "right", true) }); $(this).find(".ticker-item.item_1").css({ left: 0 }); $(this).attr("data-count", $(this).find(".ticker-item").length); $(this).find(".btn-left > i").css({ marginTop: ($(this).height() / 2) - 40 }); $(this).find(".btn-right > i").css({ marginTop: ($(this).height() / 2) - 40 }); $(window).scroll(function () { if (!$(this).attr("data-setup")) { $(this).attr("data-setup", "true"); var height = $(this).find(".ticker-item.item_1").height(); var count = parseInt($(this).attr("data-count")); $(this).find(".ticker-item.item_" + count).height() + 20; $(this).height(height); $(this).parent().height(height); } }); }); setTimeout( function () { resizeComponentSlide(); $(".componentticker .ticker-item.item_1").css({ left: 0 }); }, 1000); } }); } $(window).on('resize', function () { resizeComponentSlide(); }); function resizeComponentSlide() { if ($('.componentticker .ticker-wrapper').length) { $('.componentticker .ticker-wrapper').each(function (i) { var count = parseInt($(this).attr("data-count")); //if mobile make item width 100% if ($(window).width() < 500) { var width = $('.componentticker .ticker-wrapper').width(); $(this).attr("data-width", width); $(this).find(".ticker-item").width(width -30); } else { $(this).attr("data-width", $(this).attr("data-max-width")); $(this).find(".ticker-item").width($(this).attr("data-max-width")); } var index = parseInt($(this).attr("data-index")); var height = $(this).find(".ticker-item.item_" + index).height() - 8; $(this).height(height); $(this).parent().height(height); $(this).find(".btn-left > i").css({ marginTop: ($(this).height() / 2) - 20 }); $(this).find(".btn-right > i").css({ marginTop: ($(this).height() / 2) - 20 }); $(this).find(".btn-left").css({ height: $(this).height() }); $(this).find(".btn-right").css({ height: $(this).height() }); }); $('.componentticker .contentblock > div').each(function (index) { var wrapperHeight = $(this).height(); var textWrapper = $(this).find('.inner-text'); var textHeight = textWrapper.height(); var newHeight = wrapperHeight - textHeight; textWrapper.css("padding-top", (newHeight / 2)); }); } } function componentSlide(ctlId, direction, clicked) { $this = $('.componentticker[data-widget-id="' + ctlId + '"]').find('.ticker-wrapper'); if ($this.isInViewport()) { if (!clicked && !$this.hasClass('hovered') || clicked) { var width = parseInt($this.attr("data-width")); var index = parseInt($this.attr("data-index")); var count = parseInt($this.attr("data-count")); if (direction == 'left') { if (clicked && index == count) { return; } width = width * index; width = width - 9; //if mobile make item width 100% if ($(window).width() < 500) { if (index != count) { $this.find(".ticker-item.item_1").animate({ marginLeft: "-" + width }, 500); $this.attr("data-index", index + 1); } } else if ($(window).width() > 1400) { if ((index + 5) <= count) { $this.find(".ticker-item.item_1").animate({ marginLeft: "-" + width }, 500); $this.attr("data-index", index + 1); } } else if ($(window).width() > 992) { if ((index + 4) <= count) { $this.find(".ticker-item.item_1").animate({ marginLeft: "-" + width }, 500); $this.attr("data-index", index + 1); } } else { if ((index + 3) <= count) { $this.find(".ticker-item.item_1").animate({ marginLeft: "-" + width }, 500); $this.attr("data-index", index + 1); } } } else if (index > 1 && direction == 'right') { width = width * (index - 2); width = width - 9; if (index == 2) { width = '15'; } else { width = "-" + width } $this.find(".ticker-item.item_1").animate({ marginLeft: width }, 500); $this.attr("data-index", index - 1); } index = parseInt($this.attr("data-index")); $this.find(".btn-left > i").css({ marginTop: ($this.height() / 2) - 20 }); $this.find(".btn-right > i").css({ marginTop: ($this.height() / 2) - 20 }); } } } } if (!window.widgets) { window.widgets = {}; } window.widgets.emailform = { init: function (args) { return { submitForm: function () { if (typeof (validateChildNodes) != 'undefined') { // This might not be used so check if present if (!validateChildNodes(this.element)) { return; // Invalid } } var buttonText = $('#EmailForm_' + this.id + '_lnkSubmit').val(); $('#EmailForm_' + this.id + '_lnkSubmit').val('Please wait...').attr('disabled', true); var data = {}; var $questions = this.element.find(':input[id*=Question]'); // Even though "none" questions dont have any inputs we still need to iterate through them or i will be wrong for (var i = 0; i < $questions.length; i++) { var $question = $($questions[i]); if (typeof ($question.length && $question[0].checkValidity) == 'function') { if (!$question[0].checkValidity()) { $question.css({ outline: 'solid 2px #f00' }).addClass('invalid'); $question.blur(function () { $(this).css({ outline: 'none' }).removeClass('invalid'); }); $question[0].focus(); $('#EmailForm_' + this.id + '_lnkSubmit').val(buttonText).removeAttr('disabled'); return; } } if ($question.is(':checkbox,:radio')) { data[$question.attr('data')] = $question.is(':checked'); } else { data[$question.attr('name')] = $question.val(); } } this.call('submitForm', data, this.gotResult); }, gotResult: function (widget, data, status) { if (status != 'success') { alert('An error occurred please try again.\n'); } else { widget.element.empty(); widget.element.append($('
').append($('

').text(data.result))); } } }; } }; if (!window.widgets) { window.widgets = {}; } if (hasJquery()) { window.widgets.fourImageBlock = { windowEventsAttached: false, setupImages: function ($wrapper) { if ($wrapper.hasClass('setup')) { return false; } if (!isInViewport($wrapper)) { return true; } $wrapper.addClass('setup'); var itemWidth = $wrapper.children('.four-image-item.item_1').width(); $wrapper.children('.four-image-item').animate({ 'right': itemWidth + 'px' }, 500, function () { $wrapper.children('.four-image-item.item_2').animate({ 'top': itemWidth + 'px' }, 500, function () { $wrapper.children('.four-image-item.item_3').css({ top: itemWidth + 'px' }); $wrapper.children('.four-image-item.item_4').css({ top: itemWidth + 'px' }); $wrapper.children('.four-image-item.item_3').animate({ 'right': 0 }, 500, function () { $wrapper.children('.four-image-item.item_4').css({ right: 0 }); $wrapper.children('.four-image-item.item_4').animate({ 'top': '0' }, 500, function () { // Animation complete. }); }); }); }); return true; }, animateImages: function () { $('.four-image-wrapper').each(() => { var $wrapper = $(this); if (!window.widgets.fourImageBlock.setupImages($wrapper)) { var itemWidth = $wrapper.parent().parent().height() / 2; $wrapper.children('.four-image-item.item_1').width(itemWidth).height(itemWidth).css({ right: itemWidth }); $wrapper.children('.four-image-item.item_2').width(itemWidth).height(itemWidth).css({ right: itemWidth, top: itemWidth + 'px' }); $wrapper.children('.four-image-item.item_3').width(itemWidth).height(itemWidth).css({ top: itemWidth + 'px' }); $wrapper.children('.four-image-item.item_4').width(itemWidth).height(itemWidth).css({ top: 0 }); } }); }, setupSiteUi: function () { // This function will be invoked multiple times and should handle that if (!window.widgets.fourImageBlock.windowEventsAttached) { $(window).on('resize', window.widgets.fourImageBlock.animateImages); $(window).scroll(window.widgets.fourImageBlock.animateImages); window.widgets.fourImageBlock.windowEventsAttached = true; } $('.fourimageblock > div').height('100%'); $('.four-image-wrapper').each(function () { var $wrapper = $(this); var itemWidth = $wrapper.parent().parent().height() / 2; $wrapper.width('100%').css({ position: 'relative' }); $wrapper.children('.four-image-item').width(itemWidth).height(itemWidth).css({ right: 0, position: 'absolute' }); $wrapper.children('.four-image-item.item_1').css('z-index', 4); $wrapper.children('.four-image-item.item_2').css('z-index', 3); $wrapper.children('.four-image-item.item_3').css('z-index', 2); $wrapper.children('.four-image-item.item_4').css('z-index', 1); }); window.widgets.fourImageBlock.animateImages(); } }; window.widgets.fourImageBlock.setupSiteUi(); $(document).ready(function () { window.widgets.fourImageBlock.setupSiteUi(); }); } //TODO: Craig: This widget hasn't been modified and wont work when loaded asyncronously, how do I test it? const container = document.getElementById('google-reviews'); let currentIndex = 0; let itemsPerSlide = 3; function setItemsPerSlide() { const screenWidth = window.innerWidth; if (screenWidth < 760) { itemsPerSlide = 1; } else if (screenWidth < 1100) { itemsPerSlide = 2; } else { itemsPerSlide = 3; } const carouselItems = document.querySelectorAll('.review-carousel-item'); carouselItems.forEach(item => { if (screenWidth < 760) { item.style.flex = `0 0 calc(100% / ${itemsPerSlide})`; } else if (screenWidth < 1100) { item.style.flex = `0 0 calc((100% - 15px) / ${itemsPerSlide})`; } else { item.style.flex = `0 0 calc((100% - 25px) / ${itemsPerSlide})`; } }); } async function getPlaceDetails() { const apiKey = container.getAttribute('data-api-key'); const placeId = container.getAttribute('data-id'); const url = `/WidgetLoader.ashx?reviews=1&placeId=${placeId}&apiKey=${apiKey}`; const response = await fetch(url); const data = await response.json(); return data.result; } function filterFiveStarReviews(reviews) { return reviews.filter(review => review.rating === 5); } function createReviewElement(review) { const div = document.createElement('div'); div.className = 'review-carousel-item'; div.innerHTML = `

★★★★★

${review.text}

${review.author_name}
${review.author_name}
${review.relative_time_description}
`; return div; } function updateArrows(totalItems) { const leftArrow = document.querySelector('.review-arrow.left'); const rightArrow = document.querySelector('.review-arrow.right'); if (currentIndex === 0) { leftArrow.classList.add('disabled'); } else { leftArrow.classList.remove('disabled'); } if (currentIndex >= totalItems - itemsPerSlide) { rightArrow.classList.add('disabled'); } else { rightArrow.classList.remove('disabled'); } } function scrollCarousel() { const carouselInner = document.querySelector('.review-carousel-inner'); const totalItems = document.querySelectorAll('.review-carousel-item').length; const itemWidth = carouselInner.clientWidth / itemsPerSlide; const translateValue = -currentIndex * itemWidth; carouselInner.style.transform = `translateX(${translateValue}px)`; updateArrows(totalItems); } function manualScrollCarousel(direction) { const items = document.querySelectorAll('.review-carousel-item'); const totalItems = items.length; if (direction === 'left') { currentIndex = Math.max(currentIndex - itemsPerSlide, 0); } else { currentIndex = Math.min(currentIndex + itemsPerSlide, totalItems - itemsPerSlide); } scrollCarousel(); } async function displayReviews() { const placeDetails = await getPlaceDetails(); const reviews = placeDetails.reviews; const fiveStarReviews = filterFiveStarReviews(reviews); const reviewCount = placeDetails.user_ratings_total; const averageRating = placeDetails.rating; const carouselInner = document.querySelector('.review-carousel-inner'); document.getElementById('review-count').textContent = reviewCount; fiveStarReviews.forEach(review => { const reviewElement = createReviewElement(review); carouselInner.appendChild(reviewElement); }); document.querySelector('.review-arrow.left').addEventListener('click', () => manualScrollCarousel('left')); document.querySelector('.review-arrow.right').addEventListener('click', () => manualScrollCarousel('right')); updateAverageRatingStars(averageRating); setItemsPerSlide(); scrollCarousel(); } function updateAverageRatingStars(averageRating) { const starsContainer = document.getElementById('average-rating-stars'); starsContainer.innerHTML = ''; const fullStars = Math.floor(averageRating); const halfStar = averageRating % 1 >= 0.5 ? 1 : 0; const emptyStars = 5 - fullStars - halfStar; for (let i = 0; i < fullStars; i++) { starsContainer.innerHTML += ''; } if (halfStar) { starsContainer.innerHTML += ''; } for (let i = 0; i < emptyStars; i++) { starsContainer.innerHTML += ''; } starsContainer.style.color = 'gold'; starsContainer.style.fontSize = '24px'; } window.addEventListener('load', () => { if (container) { displayReviews(); } }); window.addEventListener('resize', () => { if (container) { setItemsPerSlide(); scrollCarousel(); } }); //TODO: Craig: This widget hasn't been modified and wont work when loaded asyncronously, how do I test it? $(document).ready(function () { if ($('#pnlContentViewContent').length) { //cms preview mode $('.instagram-feed > div').empty(); //TODO: Craig: Why? Let's make this work $('.instagram-feed > div').html("Instragram Feed Unavilable in CMS Preview Mode"); } else if ($('.instagram-data').length) { var data = $('.instagram-data').attr("data-id"); var url = "/WidgetLoader.ashx"; fetch(url, { method: "post", body: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ).then(function (response) { // The API call was successful! return response.text(); }).then(function (html) { if (html.length) { $('.instagram-feed > div').empty(); $('.instagram-feed > div').html(html); instaImageResize(); instaImageLoad(); } else { //alert('not found'); } }).catch(function (err) { console.error(err); }); } }); function instaImageLoad() { $('.insta-item').each(function (i, obj) { var $this = $(this); var data = $this.attr("data-id"); var url = "/WidgetLoader.ashx?img=1"; fetch(url, { method: "post", body: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ).then(function (response) { // The API call was successful! return response.text(); }).then(function (html) { if (html.length) { $this.empty(); $this.html(html); } else { $this.html("Not Found"); } }).catch(function (err) { $this.html("Not Found"); }); }); } $(window).on('resize', function () { instaImageResize(); }); function instaImageResize() { if ($('.instagram-feed').length) { //remove margin from width var itemMargin = 0; if ($('.insta-item').css('margin') !== undefined) { itemMargin = $('.insta-item').css('margin').replace('px', ''); } var widthPercentage = 10; if ($(window).width() < 960) { var mobileCols = $('.instagram-feed > div').attr("data-mc"); var mobileWidth = $('.instagram-feed > div').attr("data-mw"); mobileWidth = 100 / mobileCols; mobileWidth = Math.floor(mobileWidth * 100) / 100; widthPercentage = mobileWidth; } else { var desktopCols = $('.instagram-feed > div').attr("data-dc"); var desktopWidth = $('.instagram-feed > div').attr("data-dw"); desktopWidth = 100 / desktopCols; desktopWidth = Math.floor(desktopWidth * 100) / 100; widthPercentage = desktopWidth; } itemMargin = itemMargin * 2; widthPercentage = Math.floor(widthPercentage * 100) / 100; $('.insta-item').width("calc(" + widthPercentage.toFixed(2) + "% + -" + itemMargin + "px)"); } } if (!window.widgets) { window.widgets = {}; } window.widgets.newsletterform = { init: function (args) { return { submitForm: function () { if (typeof (validateChildNodes) != 'undefined') { // This might not be used so check if present if (!validateChildNodes(this.element)) { return; // Invalid } } var buttonText = $('#NewsletterForm_' + this.id + '_lnkSubmit').val(); $('#NewsletterForm_' + this.id + '_lnkSubmit').val('Please wait...').attr('disabled', true); var data = {}; var $questions = this.element.find(':input[id*=Question]'); // Even though "none" questions dont have any inputs we still need to iterate through them or i will be wrong for (var i = 0; i < $questions.length; i++) { var $question = $($questions[i]); if (typeof ($question.length && $question[0].checkValidity) == 'function') { if (!$question[0].checkValidity()) { $question.css({ outline: 'solid 2px #f00' }).addClass('invalid'); $question.blur(function () { $(this).css({ outline: 'none' }).removeClass('invalid'); }); $question[0].focus(); $('#NewsletterForm_' + this.id + '_lnkSubmit').val(buttonText).removeAttr('disabled'); return; } } if ($question.is(':checkbox,:radio')) { data[$question.attr('data')] = $question.is(':checked'); } else { data[$question.attr('name')] = $question.val(); } } this.call('submitForm', data, this.gotResult); }, gotResult: function (widget, data, status) { if (status != 'success') { alert('An error occurred please try again.\n'); } else { widget.element.empty(); widget.element.append($('
').html(data.result)); } } }; } } /*Scrolling Widget*/ //TODO: Craig: This widget seems to work - but is missing CSS, the CSS should be embedded within the widget's folder as a .css file if (!window.widgets) { window.widgets = {}; } window.widgets.photoGallery = { setupSiteUi: function () { if ($('.scrolling-photo-wrapper').length) { if (!window.widgets.photoGallery.windowEventsAttached) { $(window).on('resize', function () { window.widgets.photoGallery.resizePhotoSlide(); }); window.widgets.photoGallery.windowEventsAttached = true; } $('.scrolling-photo-wrapper').each(function (index) { var $elem = $(this); if ($elem.data('is-setup')) { return; } $elem.data('is-setup', true); $elem.mouseenter(function () { $elem.addClass('hovered'); }).mouseleave(function () { $elem.removeClass('hovered'); }); var width = $elem.parent().parent().width(); $elem.width(width); $elem.attr("data-index", "1").attr("data-count", "0").attr("data-width", $elem.width()); var dataId = $elem.parent().parent().attr("data-widget-id"); $elem.find(".btn-right").click(function () { window.widgets.photoGallery.photoSlide(dataId, "left", true) }); $elem.find(".btn-left").click(function () { window.widgets.photoGallery.photoSlide(dataId, "right", true) }); $elem.find(".scrolling-item").width(width).css({ left: width }); $elem.find(".scrolling-item img").width(width); $elem.attr("data-count", $elem.find(".scrolling-item").length); $elem.find(".btn-left > i").css({ marginTop: ($elem.height() / 2) - 40 }); $elem.find(".btn-right > i").css({ marginTop: ($elem.height() / 2) - 40 }); setInterval(function () { window.widgets.photoGallery.photoSlide(dataId, 'left', false); }, 8000); $(window).scroll(function () { if (!$elem.attr("data-setup")) { $elem.attr("data-setup", "true"); var height = $elem.find(".scrolling-item.item_1 img").height(); var count = parseInt($elem.attr("data-count")); $elem.find(".scrolling-item.item_" + count).height() + 20; $elem.height(height); $elem.parent().height(height); } }); }); setTimeout( function () { window.widgets.photoGallery.resizePhotoSlide(); $(".scrolling-item.item_1").css({ left: 0 }); }, 500); } }, resizePhotoSlide: function () { $('.scrolling-photo-wrapper').each(function () { var $elem = $(this); var width = parseInt($elem.parent().parent().width()); $elem.attr("data-width", width); $elem.width(width); var index = parseInt($elem.attr("data-index")); $elem.find(".scrolling-item").width(width).css({ left: width }); $elem.find(".scrolling-item.item_" + index).css({ left: 0 }); $elem.find(".scrolling-item img").width(width); var height = $elem.find(".scrolling-item.item_" + index + " img").height(); $elem.height(height); $elem.parent().height(height); $elem.find(".btn-left > i").css({ marginTop: ($elem.height() / 2) - 20 }); $elem.find(".btn-right > i").css({ marginTop: ($elem.height() / 2) - 20 }); }); }, photoSlide: function (ctlId, direction, clicked) { $this = $('.photogallery[data-widget-id="' + ctlId + '"]').find('.scrolling-photo-wrapper'); if (isInViewport($this)) { if (!clicked && !$this.hasClass('hovered') || clicked) { var width = parseInt($this.parent().parent().width()); var index = parseInt($this.attr("data-index")); var count = parseInt($this.attr("data-count")); if (direction == 'left') { if (index == count) { return; } var height = $this.find(".scrolling-item.item_" + (index + 1) + " img").height(); $this.height(height); $this.parent().height(height); if (index == 2) { $this.find(".scrolling-item.item_1").css({ left: width }); $this.find(".scrolling-item.item_" + count).css({ left: width }); } $this.find(".scrolling-item.item_" + index).animate({ left: "-" + width }, 500); if (index == count) { $this.find(".scrolling-item").css({ left: width }); index = 0; } $this.find(".scrolling-item.item_" + (index + 1)).animate({ left: "0" }, 500); $this.attr("data-index", index + 1); } else if (index > 1 && direction == 'right') { var height = $this.find(".scrolling-item.item_" + (index - 1) + " img").height(); $this.height(height); $this.parent().height(height); if (index == 2) { $this.find(".scrolling-item.item_1").css({ left: - width }); } $this.find(".scrolling-item.item_" + index).animate({ left: width }, 500); $this.find(".scrolling-item.item_" + (index - 1)).animate({ left: "0" }, 500); $this.attr("data-index", index - 1); } index = parseInt($this.attr("data-index")); $this.find(".icons i").removeClass('selected'); $this.find(".icons .item_" + index).addClass('selected'); $this.find(".scrolling-item img").width(width); $this.find(".btn-left > i").css({ marginTop: ($this.height() / 2) - 20 }); $this.find(".btn-right > i").css({ marginTop: ($this.height() / 2) - 20 }); } } } }; window.widgets.photoGallery.setupSiteUi(); $(document).ready(function () { window.widgets.photoGallery.setupSiteUi() }); /*light-box*/ if (!window.widgets) { window.widgets = {}; } window.widgets.photoLightBox = { open: function (elem) { var $root = $(elem).parents('.widget:first'); $root.find('.lightbox-modal').show(); }, close: function (elem) { var $root = $(elem).parents('.widget:first'); $root.find('.lightbox-modal').hide(); }, getIndex: function (elem) { var $root = $(elem).parents('.widget:first'); var index = $root.data('lightboxIndex'); if (index !== undefined) { return index; } $root.data('lightboxIndex', 1); return 1; }, changeSlide: function (elem, n) { var index = window.widgets.photoLightBox.getIndex(elem) + n; window.widgets.photoLightBox.update(elem, index); }, setSlide: function (elem, n) { window.widgets.photoLightBox.update(elem, n); }, update: function (elem, index) { var $root = $(elem).parents('.widget:first'); var slides = $root.find('.lightbox-slide'); if (index > slides.length) { index = 1 } if (index < 1) { index = slides.length } $(slides).hide(); if ($(window).width() > 575) { var imgWidth = $(slides[index - 1]).find('img')[0].width; $(slides[index - 1]).parent().width(imgWidth); } $(slides[index - 1]).show(); $root.data('lightboxIndex', index); } }; //TODO: Joe refactor /*Scrolling Widget*/ if ('undefined' == typeof window.jQuery) { } else { window.onload = function () { $(document).ready(function () { $.fn.isInViewport = function () { if ($(this).offset()) { var elementTop = $(this).offset().top; var elementBottom = elementTop + $(this).outerHeight(); var viewportTop = $(window).scrollTop(); var viewportBottom = viewportTop + $(window).height(); return elementBottom > viewportTop && elementTop < viewportBottom; } else { return false; } }; if ($('.componentscroller .scrolling-wrapper').length) { $('.componentscroller .contentblock > div').each(function (index) { $(this).wrapInner('
'); }); $('.componentscroller .scrolling-wrapper').mouseenter(function () { $(this).addClass('hovered'); }).mouseleave(function () { $(this).removeClass('hovered'); }); $('.componentscroller .scrolling-wrapper').each(function (i) { var width = $(this).parent().parent().width(); $(this).width(width); $(this).attr("data-index", "1").attr("data-count", "0").attr("data-width", $(this).width()); var dataId = $(this).parent().parent().attr("data-widget-id"); $(this).find(".btn-right").click(function () { componentSlide(dataId, "left", true) }); $(this).find(".btn-left").click(function () { componentSlide(dataId, "right", true) }); $(this).find(".scrolling-item").width(width).css({ left: width }); $(this).find(".scrolling-item.item_1").css({ left: 0 }); $(this).attr("data-count", $(this).find(".scrolling-item").length); $(this).find(".btn-left > i").css({ marginTop: ($(this).height() / 2) - 40 }); $(this).find(".btn-right > i").css({ marginTop: ($(this).height() / 2) - 40 }); setInterval(function () { componentSlide(dataId, 'left', false); }, 8000); $(window).scroll(function () { if (!$(this).attr("data-setup")) { $(this).attr("data-setup", "true"); var height = $(this).find(".scrolling-item.item_1").height(); var count = parseInt($(this).attr("data-count")); $(this).find(".scrolling-item.item_" + count).height() + 20; $(this).height(height); $(this).parent().height(height); } }); }); setTimeout( function () { resizeComponentSlide(); $(".componentscroller .scrolling-item.item_1").css({ left: 0 }); }, 500); } }); $(window).on('resize', function () { resizeComponentSlide(); }); } function resizeComponentSlide() { if ($('.componentscroller .scrolling-wrapper').length) { $('.componentscroller .scrolling-wrapper').each(function (i) { var count = parseInt($(this).attr("data-count")); var width = parseInt($(this).parent().parent().width()); $(this).attr("data-width", width); $(this).width(width); var index = parseInt($(this).attr("data-index")); $(this).find(".scrolling-item").width(width).css({ left: width }); $(this).find(".scrolling-item.item_" + index).css({ left: 0 }); $(this).find(".scrolling-item img").width(width); var height = $(this).find(".scrolling-item.item_" + index).height() - 8; $(this).height(height); $(this).parent().height(height); $(this).find(".btn-left > i").css({ marginTop: ($(this).height() / 2) - 20 }); $(this).find(".btn-right > i").css({ marginTop: ($(this).height() / 2) - 20 }); $(this).find(".btn-left").css({ height: $(this).height() }); $(this).find(".btn-right").css({ height: $(this).height() }); }); $('.componentscroller .contentblock > div').each(function (index) { var wrapperHeight = $(this).height(); var textWrapper = $(this).find('.inner-text'); var textHeight = textWrapper.height(); var newHeight = wrapperHeight - textHeight; textWrapper.css("padding-top", (newHeight / 2)); }); } } function componentSlide(ctlId, direction, clicked) { $this = $('.componentscroller[data-widget-id="' + ctlId + '"]').find('.scrolling-wrapper'); if ($this.isInViewport()) { if (!clicked && !$this.hasClass('hovered') || clicked) { var width = parseInt($this.parent().parent().width()); var index = parseInt($this.attr("data-index")); var count = parseInt($this.attr("data-count")); if (direction == 'left') { if (clicked && index == count) { return; } var findIndex = index + 1; var height = $this.find(".scrolling-item.item_" + findIndex).height() - 8; $this.height(height); $this.parent().height(height); if (index == 2) { $this.find(".scrolling-item.item_1").css({ left: width }); $this.find(".scrolling-item.item_" + count).css({ left: width }); } $this.find(".scrolling-item.item_" + index).animate({ left: "-" + width }, 500); if (index == count) { $this.find(".scrolling-item").css({ left: width }); index = 0; } $this.find(".scrolling-item.item_" + (index + 1)).animate({ left: "0" }, 500); $this.attr("data-index", index + 1); } else if (index > 1 && direction == 'right') { var findIndex = index - 1; var height = $this.find(".scrolling-item.item_" + findIndex).height() - 8; $this.height(height); $this.parent().height(height); if (index == 2) { $this.find(".scrolling-item.item_1").css({ left: - width }); } $this.find(".scrolling-item.item_" + index).animate({ left: width }, 500); $this.find(".scrolling-item.item_" + (index - 1)).animate({ left: "0" }, 500); $this.attr("data-index", index - 1); } index = parseInt($this.attr("data-index")); $this.find(".icons i").removeClass('selected'); $this.find(".icons .item_" + index).addClass('selected'); $this.find(".scrolling-item img").width(width); $this.find(".btn-left > i").css({ marginTop: ($this.height() / 2) - 20 }); $this.find(".btn-right > i").css({ marginTop: ($this.height() / 2) - 20 }); } } } } if (!window.widgets) { window.widgets = {}; } function setupYtPlayers() { // This is invoked on load/widget dynamically added (by setupSiteUi) and when the yt player API is ready if (!window.ytPlayerApiReady) { return; } var e = $(".video-data"); if (void 0 !== e) for (var a = 0; a < e.length; a++) { var t = createPlayer(e[a].attributes["video-data"].value.split(",")); players[a] = t } } function onYouTubePlayerAPIReady() { window.ytPlayerApiReady = true; setupYtPlayers(); } var players = new Array; function createPlayer(e) { return new YT.Player(e[0], { width: "100%", videoId: e[4], playerVars: { controls: e[1], autoplay: e[2], rel: 0, fs: 1, origin: "https://" + $(location) .attr('host') }, events: { onReady: onPlayerReady, onStateChange: onPlayerStateChange } }) } function onPlayerReady(e) { var a = e.target.getIframe() .attributes["video-data"].value; a.length && (1 == a.split(",")[2] && (e.target.mute(), e.target.playVideo())) } function onPlayerStateChange(e) { if (e.data == YT.PlayerState.ENDED) { var a = e.target.getIframe() .attributes["video-data"].value; if (a.length) 1 == a.split(",")[3] && (e.target.seekTo(0), e.target.playVideo()) } } window.widgets.youtube = { init: function () { }, setupSiteUi: function () { if (!hasJquery()) { return; } if ($(".video-data").length && !$('#youtube_script') .length) { var e = document.createElement("script"); e.id = 'youtube_script' e.src = "https://www.youtube.com/player_api"; var t = document.getElementsByTagName("script")[0]; t.parentNode.insertBefore(e, t) } setupYtPlayers(); } } window.widgets.youtube.setupSiteUi(); hasJquery && $(document).ready(window.widgets.youtube.setupSiteUi);