', { 'class': 'writer clearfix test2' })\r\n .append($('
![]()
', { 'class': 'writer__image', src: testimonial.Image.Src, alt: testimonial.Image.Alt }))\r\n .append($('
', { 'class': 'writer__name', itemprop: 'author' }).text(testimonial.Author))\r\n .append($('', { itemprop: 'datePublished', content: testimonial.QuoteDate }).text(testimonial.QuoteDateSummary))\r\n )\r\n .append($('', { 'class': testimonial.RatingClass, itemprop: 'reviewRating', itemscope: 'itemscope', itemtype: 'http://schema.org/Rating', ratingTitle: testimonial.RatingTitle })\r\n .append($('', { itemprop: 'ratingValue', content: testimonial.RatingValue }))\r\n )\r\n .append($('').text(testimonial.RatingTitle))\r\n ) \r\n )\r\n );\r\n });\r\n }\r\n\r\n})(window.jQuery);","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CSSCONSTANTS = CSSCONSTANTS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.setupProviderList = function () {\r\n var $providersVisible;\r\n\r\n enquire.register(CSSCONSTANTS.nonMobileMinWidthMQ, {\r\n\r\n match: function () {\r\n $providersVisible = $('.' + CSSCONSTANTS.visibleProvidersClass);\r\n CONFUSEDCMS.createImages($providersVisible);\r\n },\r\n unmatch: function () {\r\n $providersVisible = $('.' + CSSCONSTANTS.visibleProvidersClass);\r\n CONFUSEDCMS.removeImages($providersVisible);\r\n }\r\n }, true);\r\n\r\n \r\n CONFUSEDCMS.createMoreProvidersButton();\r\n CONFUSEDCMS.setupProviderFilters();\r\n \r\n };\r\n\r\n CONFUSEDCMS.setupProviderFilters = function () {\r\n \r\n var $providers = $('.' + CSSCONSTANTS.providersClass),\r\n $providerFilters = $('.' + CSSCONSTANTS.providerFilterClass),\r\n $providerFilterShowAll = $('.' + CSSCONSTANTS.providerFilterShowAllClass),\r\n providerFilterActiveClass = CSSCONSTANTS.backgroundBlueClass,\r\n providerFilterInactiveClass = CSSCONSTANTS.backgroundPastel2Class;\r\n\r\n $.each($providerFilters, function () {\r\n var $this = $(this),\r\n lettersToFilter = $this.text();\r\n\r\n $this.on('click',function (e) {\r\n e.preventDefault();\r\n CONFUSEDCMS.filterProviders($providers, lettersToFilter);\r\n $providerFilterShowAll.add($providerFilters).removeClass(providerFilterActiveClass).addClass(providerFilterInactiveClass);\r\n $this.removeClass(providerFilterInactiveClass).addClass(providerFilterActiveClass);\r\n CONFUSEDCMS.removeMoreProvidersButton();\r\n });\r\n });\r\n\r\n $providerFilterShowAll.on('click',function (e) {\r\n e.preventDefault();\r\n CONFUSEDCMS.showAllProviders($providers);\r\n $providerFilterShowAll.add($providerFilters).removeClass(providerFilterActiveClass).addClass(providerFilterInactiveClass);\r\n $providerFilterShowAll.removeClass(providerFilterInactiveClass).addClass(providerFilterActiveClass);\r\n CONFUSEDCMS.removeMoreProvidersButton();\r\n });\r\n };\r\n \r\n CONFUSEDCMS.filterProviders = function ($providers, lettersToFilter) {\r\n\r\n $providers.removeClass(CSSCONSTANTS.visibleProvidersClass);\r\n $providers.addClass(CSSCONSTANTS.hiddenProvidersClass);\r\n \r\n $.each($providers, function () {\r\n var $this = $(this),\r\n thisProviderHref = $this.find('a').attr('href'),\r\n $thisProviderImage = $this.find('img'),\r\n thisProviderName,\r\n thisProviderFirstLetter;\r\n \r\n var thisProviderHrefSegment = thisProviderHref.lastIndexOf('/');\r\n thisProviderFirstLetter = thisProviderHref.charAt(thisProviderHrefSegment + 1).toUpperCase();\r\n\r\n if (lettersToFilter.indexOf(thisProviderFirstLetter) !== -1) {\r\n $this.removeClass(CSSCONSTANTS.hiddenProvidersClass);\r\n $this.addClass(CSSCONSTANTS.visibleProvidersClass);\r\n\r\n if (($thisProviderImage.length < 1) && (!matchMedia('(max-width: ' + CSSCONSTANTS.mobileMaxWidth + ')').matches)) {\r\n CONFUSEDCMS.createImages($this);\r\n }\r\n }\r\n \r\n });\r\n };\r\n\r\n CONFUSEDCMS.createImages = function ($providersToShowImages) {\r\n\r\n $.each($providersToShowImages, function () {\r\n var $provider = $(this).find('a'),\r\n $providerImage,\r\n thisImageSrc = $provider.attr('data-img');\r\n \r\n $providerImage = $('
', {\r\n src: thisImageSrc,\r\n alt : $provider.text()\r\n });\r\n $provider.text('');\r\n $providerImage.appendTo($provider);\r\n }); \r\n };\r\n\r\n CONFUSEDCMS.removeImages = function ($providersToRemoveImages) { /* for removing images from visible providers when switching to mobile view */\r\n $.each($providersToRemoveImages, function () {\r\n var $this = $(this),\r\n $providerLink = $this.find('a'),\r\n $providerImg = $providerLink.find('img'),\r\n providerName = $providerImg.attr('alt');\r\n console.log(providerName);\r\n $providerLink.text(providerName);\r\n $providerImg.remove();\r\n });\r\n };\r\n\r\n CONFUSEDCMS.createMoreProvidersButton = function () {\r\n var $providerList = $('.' + CSSCONSTANTS.providerListClass),\r\n $hiddenProviders = $('.' + CSSCONSTANTS.hiddenProvidersClass),\r\n $moreLink,\r\n moreLinkText = 'Show more';\r\n\r\n if ($hiddenProviders.length >= 1) {\r\n\r\n $moreLink = $('', {\r\n 'class': CSSCONSTANTS.providerListMoreLinkClass,\r\n href: '#',\r\n text: moreLinkText\r\n });\r\n\r\n $moreLink.on('click', function (e) {\r\n e.preventDefault();\r\n CONFUSEDCMS.showMoreProviders();\r\n });\r\n \r\n $moreLink.insertAfter($providerList);\r\n }\r\n };\r\n\r\n CONFUSEDCMS.removeMoreProvidersButton = function () {\r\n var $moreLink = $('.' + CSSCONSTANTS.providerListMoreLinkClass);\r\n $moreLink.remove();\r\n };\r\n\r\n CONFUSEDCMS.showAllProviders = function ($providers) {\r\n $providers.removeClass(CSSCONSTANTS.hiddenProvidersClass);\r\n $providers.addClass(CSSCONSTANTS.visibleProvidersClass);\r\n $.each($providers, function () {\r\n var $this = $(this),\r\n $thisProviderImage = $this.find('img');\r\n\r\n if (($thisProviderImage.length < 1) && (!matchMedia('(max-width: ' + CSSCONSTANTS.mobileMaxWidth + ')').matches)) {\r\n CONFUSEDCMS.createImages($this);\r\n }\r\n });\r\n };\r\n\r\n CONFUSEDCMS.showMoreProviders = function () {\r\n var $hiddenProviders = $('.' + CSSCONSTANTS.hiddenProvidersClass),\r\n $moreLink = $('.' + CSSCONSTANTS.providerListMoreLinkClass);\r\n \r\n $.each($hiddenProviders, function () {\r\n var $this = $(this);\r\n\r\n $this.removeClass(CSSCONSTANTS.hiddenProvidersClass).addClass(CSSCONSTANTS.visibleProvidersClass);\r\n\r\n });\r\n\r\n if (!matchMedia('(max-width: ' + CSSCONSTANTS.mobileMaxWidth + ')').matches) {\r\n CONFUSEDCMS.createImages($hiddenProviders);\r\n }\r\n \r\n $moreLink.remove();\r\n\r\n };\r\n\r\n})(window.jQuery);\r\n\r\n\r\n","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CSSCONSTANTS = CSSCONSTANTS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.responsiveTabs = function () {\r\n var $tabSets = $('.' + CSSCONSTANTS.responsiveTabsClass);\r\n\r\n if (!$tabSets.hasClass(CSSCONSTANTS.responsiveTabsEnabledClass)) {\t// if we haven't already called this function and enabled tabs\r\n $tabSets.addClass(CSSCONSTANTS.responsiveTabsEnabledClass);\r\n\r\n\t\t\t//loop through all sets of tabs on the page\r\n\t\t\tvar tablistcount = 1;\r\n\r\n\t\t\t$tabSets.each(function() {\r\n\r\n\t\t\t\tvar $tabs = $(this);\r\n\r\n\t\t\t\t// add tab heading and tab panel classes\r\n\t\t\t\t$tabs.children(':header').addClass(CSSCONSTANTS.responsiveTabsHeadingClass);\r\n\t\t\t\t$tabs.children('div').addClass(CSSCONSTANTS.responsiveTabsPanelClass);\r\n\r\n\t\t\t\t// determine if markup already identifies the active tab panel for this set of tabs\r\n\t\t\t\t// if not then set first heading and tab to be the active one\r\n\t\t\t\tvar $activePanel = $tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelActiveClass);\r\n\t\t\t\tif(!$activePanel.length) {\r\n\t\t\t\t $activePanel = $tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClass).first().addClass(CSSCONSTANTS.responsiveTabsPanelActiveClass);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClass).not('.' + CSSCONSTANTS.responsiveTabsPanelActiveClass).hide().attr('aria-hidden', 'true'); //hide all except active panel\r\n\t\t\t\t$activePanel.attr('aria-hidden', 'false');\r\n\t\t\t\t/* make active tab panel hidden for mobile */\r\n\t\t\t\t$activePanel.addClass(CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass);\r\n\r\n\t\t\t\t// wrap tabs in container - to be dynamically resized to help prevent page jump\r\n\t\t\t\tvar $tabsWrapper = $('
', { 'class': CSSCONSTANTS.responsiveTabsWrapperClass });\r\n\t\t\t\t$tabs.wrap($tabsWrapper);\r\n\r\n\t\t\t\tvar highestHeight = 0;\r\n\r\n\t\t\t\t// determine height of tallest tab panel. Used later to prevent page jump when tabs are clicked\r\n\t\t\t\t$tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClass).each(function () {\r\n\t\t\t\t\tvar tabHeight = $(this).height();\r\n\t\t\t\t\tif (tabHeight > highestHeight) {\r\n\t\t\t\t\t\thighestHeight = tabHeight;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\tvar $tabList;\r\n\r\n\t\t\t //create the tab list\r\n\t\t\t\tif ($tabs.hasClass(CSSCONSTANTS.responsiveTabsStepsClass)) {\r\n\t\t\t\t $tabList = $('
', { 'class': CSSCONSTANTS.responsiveTabsListClass, 'role': 'tablist' });\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t $tabList = $('', { 'class': CSSCONSTANTS.responsiveTabsListClass, 'role': 'tablist' });\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\r\n\t\t\t\t//loop through each heading in set\r\n\t\t\t\tvar tabcount = 1;\r\n\t\t\t\t$tabs.find('.' + CSSCONSTANTS.responsiveTabsHeadingClass).each(function () {\r\n\r\n\t\t\t\t var $tabHeading = $(this);\r\n\t\t\t\t var $tabPanel = $(this).next();\r\n\r\n\t\t\t\t $tabHeading.attr('tabindex', 0);\r\n\r\n\t\t\t\t // CREATE TAB ITEMS (VISIBLE ON DESKTOP)\r\n\t\t\t\t //create tab list item from heading\r\n\t\t\t\t //associate tab list item with tab panel\r\n\t\t\t\t var $tabListItem = $('', { \r\n\t\t\t\t id: 'tablist' + tablistcount + '-tab' + tabcount,\r\n\t\t\t\t 'aria-controls': 'tablist' + tablistcount +'-panel' + tabcount,\r\n\t\t\t\t 'role': 'tab',\r\n\t\t\t\t tabindex: 0,\r\n\t\t\t\t text: $tabHeading.text(),\r\n\t\t\t\t keydown: function (objEvent) {\r\n\t\t\t\t if (objEvent.keyCode === 13) { // if user presses 'enter'\r\n\t\t\t\t $tabListItem.click();\r\n\t\t\t\t }\r\n\t\t\t\t },\r\n\t\t\t\t click: function() {\r\n\t\t\t\t //Show associated panel\r\n\r\n\t\t\t\t //set height of tab container to highest panel height to avoid page jump\r\n\t\t\t\t $tabsWrapper.css('height', highestHeight);\r\n\r\n\t\t\t\t // remove hidden mobile class from any other panel as we'll want that panel to be open at mobile size\r\n\t\t\t\t $tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass).removeClass(CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t // close current panel and remove active state from its (hidden on desktop) heading\r\n\t\t\t\t $tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelActiveClass).toggle().removeClass(CSSCONSTANTS.responsiveTabsPanelActiveClass).attr('aria-hidden', 'true').prev().removeClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t //make this tab panel active\r\n\t\t\t\t $tabPanel.toggle().addClass(CSSCONSTANTS.responsiveTabsPanelActiveClass).attr('aria-hidden', 'false');\r\n\r\n\t\t\t\t //make the hidden heading active\r\n\t\t\t\t $tabHeading.addClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\r\n\t\t\t\t //remove active state from currently active tab list item\r\n\t\t\t\t $tabList.find('.' + CSSCONSTANTS.responsiveTabsListItemActiveClass).removeClass(CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\r\n\t\t\t\t //make this tab active\r\n\t\t\t\t $tabListItem.parent().addClass(CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\r\n\t\t\t\t //reset height of tab panels to auto\r\n\t\t\t\t $tabsWrapper.css('height', 'auto');\r\n\t\t\t\t }\r\n\t\t\t\t });\r\n\r\n\t\t\t\t //create list item to contain tab\r\n\t\t\t\t var $tabListItemLi = $('', { 'class': CSSCONSTANTS.responsiveTabsListItemClass });\r\n\t\t\t\t $tabListItem.prependTo($tabListItemLi);\r\n\r\n\t\t\t\t //associate tab panel with tab list item\r\n\t\t\t\t $tabPanel.attr({\r\n\t\t\t\t 'role': 'tabpanel',\r\n\t\t\t\t 'aria-labelledby': $tabListItem.attr('id'),\r\n\t\t\t\t id: 'tablist' + tablistcount + '-panel' + tabcount\r\n\t\t\t\t });\r\n\r\n\t\t\t\t // if this is the active panel then make it the active tab item\r\n\t\t\t\t if ($tabPanel.hasClass(CSSCONSTANTS.responsiveTabsPanelActiveClass)) {\r\n\t\t\t\t $tabListItem.parent().addClass(CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\t\t\t\t }\r\n\r\n\t\t\t\t\t// add tab item\r\n\t\t\t\t\t$tabList.append($tabListItemLi);\r\n\r\n\t\t\t\t\t\r\n\t\t\t\t\t// TAB HEADINGS (VISIBLE ON MOBILE)\r\n\t\t\t\t\t// if user presses 'enter' on tab heading trigger the click event\r\n\t\t\t\t\t$tabHeading.keydown(function(objEvent) {\r\n\t\t\t\t\t\tif (objEvent.keyCode === 13) {\r\n\t\t\t\t\t\t\t$tabHeading.click();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t//toggle tab panel if click heading (on mobile)\r\n\t\t\t\t\t$tabHeading.click(function() {\r\n\r\n\t\t\t\t\t\t// remove any hidden mobile class\r\n\t\t\t\t\t $tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass).removeClass(CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass);\r\n\r\n\t\t\t\t\t\t// if this isn't currently active\r\n\t\t\t\t\t\tif (!$tabHeading.hasClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass)) {\r\n\r\n\t\t\t\t\t\t\tvar oldActivePos,\r\n\t\t\t\t\t\t\t\t$activeHeading = $tabs.find('.' + CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t// if there is an active heading, get its position\r\n\t\t\t\t\t\t\tif($activeHeading.length) {\r\n\t\t\t\t\t\t\t\toldActivePos = $activeHeading.offset().top;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t// close currently active panel and remove active state from any hidden heading\r\n\t\t\t\t\t\t\t$tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelActiveClass).slideToggle().removeClass(CSSCONSTANTS.responsiveTabsPanelActiveClass).prev().removeClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t//close all tabs\r\n\t\t\t\t\t\t\t$tabs.find('.' + CSSCONSTANTS.responsiveTabsPanelClass).hide().attr('aria-hidden', 'true');\r\n\r\n\t\t\t\t\t\t\t//open this panel\r\n\t\t\t\t\t\t\t$tabPanel.slideToggle().addClass(CSSCONSTANTS.responsiveTabsPanelActiveClass).attr('aria-hidden', 'false');\r\n\r\n\t\t\t\t\t\t\t// make this heading active\r\n\t\t\t\t\t\t\t$tabHeading.addClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\r\n\t\t\t\t\t\t\tvar $currentActive = $tabs.find('.' + CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\r\n\t\t\t\t\t\t\t//set the active tab list item (for desktop)\r\n\t\t\t\t\t\t\t$currentActive.removeClass(CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\t\t\t\t\t\t\tvar panelId = $tabPanel.attr('id');\r\n\t\t\t\t\t\t\tvar tabId = panelId.replace('panel','tab');\r\n\t\t\t\t\t\t\t$('#' + tabId).parent().addClass(CSSCONSTANTS.responsiveTabsListItemActiveClass);\r\n\r\n\t\t\t\t\t\t\t//scroll to active heading only if it is below previous one\r\n\t\t\t\t\t\t\tvar tabsPos = $tabs.offset().top;\r\n\t\t\t\t\t\t\tvar newActivePos = ($tabHeading.offset().top) - 15;\r\n\t\t\t\t\t\t\tif(oldActivePos < newActivePos) {\r\n\t\t\t\t\t\t\t\t$('html, body').animate({ scrollTop: tabsPos }, 0).animate({ scrollTop: newActivePos }, 400);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// if this tab panel is already active\r\n\t\t\t\t\t\telse {\r\n\r\n\t\t\t\t\t\t\t// hide panel but give it special responsive-tabs__panel--closed-accordion-only class so that it can be visible at desktop size\r\n\t\t\t\t\t\t $tabPanel.removeClass(CSSCONSTANTS.responsiveTabsPanelActiveClass).slideToggle(function () { $(this).addClass(CSSCONSTANTS.responsiveTabsPanelClosedAccordionOnlyClass); });\r\n\r\n\t\t\t\t\t\t\t//remove active heading class\r\n\t\t\t\t\t\t\t$tabHeading.removeClass(CSSCONSTANTS.responsiveTabsHeadingActiveClass);\r\n\r\n\t\t\t\t\t\t\t//don't alter classes on tabs as we want it active if put back to desktop size\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\ttabcount ++;\r\n\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// add finished tab list to its container\r\n\t\t\t\t$tabs.prepend($tabList);\r\n\r\n\t\t\t\t// next set of tabs on page\r\n\t\t\t\ttablistcount ++;\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n})(window.jQuery);\r\n","var CONFUSEDCMS = CONFUSEDCMS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.priceIndex = function () {\r\n\r\n if (window.innerWidth > 600) {\r\n $(window).scroll(function () {\r\n $('.img--infographic').each(function (e) {\r\n\r\n var image = $(this),\r\n imageSrc = image.attr('src'),\r\n imageOffset = $(this).offset().top,\r\n imageHeight = $(this).outerHeight(),\r\n windowHeight = $(window).height(),\r\n windowScroll = $(window).scrollTop();\r\n if (!image.hasClass('active')) {\r\n if (windowScroll > (imageOffset + imageHeight - windowHeight)) {\r\n image.css('opacity', '1');\r\n image.attr('src', imageSrc);\r\n image.addClass('active');\r\n } else {\r\n $(this).css('opacity', '0');\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n $('.expanded-image-button').click(function (e) {\r\n e.preventDefault();\r\n $(this).closest('.container').nextAll('.expanded-image-modal').fadeIn(300);\r\n $('.dimmer').fadeIn(300);\r\n });\r\n\r\n $('.expanded-image-modal__inner__close').click(function (e) {\r\n e.preventDefault();\r\n $(this).closest('.expanded-image-modal').fadeOut(300);\r\n $('.dimmer').fadeOut(300);\r\n });\r\n\r\n $('.video__controls a').click(function () {\r\n $('.video-header').hide();\r\n });\r\n\r\n };\r\n})(window.jQuery);","var CONFUSEDWEBSITE = CONFUSEDWEBSITE || {};\n\n(function ($) {\n $(function () {\n\n CONFUSEDWEBSITE.setupGlobalNav();\n CONFUSEDWEBSITE.skipNav();\n\n if ($('.mobile-nav').length > 0) {\n CONFUSEDWEBSITE.activateMobileNav();\n }\n\n CONFUSEDWEBSITE.setupHeaderActions();\n CONFUSEDWEBSITE.setupSearchResults();\n CONFUSEDWEBSITE.setupSearchForms();\n\n });\n\n})(window.jQuery);","var CONFUSEDCMS = CONFUSEDCMS || {};\r\nCONFUSEDCMS.VehicleDetails = CONFUSEDCMS.VehicleDetails || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n ns.Constants = {\r\n MinDate: '0001-01-01T00:00:00',\r\n ValidText: 'valid',\r\n InvalidText: 'invalid',\r\n ValidClass: 'mot-checker__results__result mot-checker__results__result--ok',\r\n InvalidClass: 'mot-checker__results__result mot-checker__results__result--alert'\r\n };\r\n\r\n ns.Utils = {\r\n FormatDate: function (date) {\r\n var d = new Date(date || Date.now()),\r\n month = '' + (d.getMonth() + 1),\r\n day = '' + d.getDate(),\r\n year = d.getFullYear();\r\n\r\n if (month.length < 2) {\r\n month = '0' + month;\r\n }\r\n if (day.length < 2) {\r\n day = '0' + day;\r\n }\r\n\r\n return [day, month, year].join('/');\r\n },\r\n ValidateForm: function ($form) {\r\n return $form.valid();\r\n }\r\n\r\n };\r\n\r\n ns.Vehicle = function () {\r\n var self = this;\r\n self.RegNumber = ko.observable('');\r\n self.MotExpiry = ko.observable('');\r\n self.Make = ko.observable('');\r\n self.Model = ko.observable('');\r\n self.Display = function() {\r\n var display = self.RegNumber();\r\n if (self.Make() !== '') {\r\n display += ', ' + self.Make() + ' ';\r\n }\r\n if (self.Model() !== '') {\r\n display += self.Model();\r\n }\r\n\r\n return display;\r\n };\r\n\r\n self.ValidExpiryDate = function() {\r\n if (self.MotExpiry() === ns.Constants.MinDate) {\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n self.ValidMot = function () {\r\n if (!self.ValidExpiryDate()) {return false;}\r\n\r\n var today = new Date();\r\n var motDate = new Date(self.MotExpiry());\r\n\r\n if (today > motDate) {\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n self.FormattedMotExpiry = function() {\r\n return ns.Utils.FormatDate(self.MotExpiry());\r\n };\r\n\r\n self.ValidityText = function() {\r\n if (self.ValidMot()) {\r\n return ns.Constants.ValidText;\r\n }\r\n\r\n return ns.Constants.InvalidText;\r\n };\r\n\r\n };\r\n\r\n ns.MotChecker = function () {\r\n var self = this;\r\n self.Vehicle = new ns.Vehicle();\r\n self.ShowSearch = ko.observable(true);\r\n self.VehicleNotFound = ko.observable(false);\r\n self.VehicleErrorOccurred = ko.observable(false);\r\n self.Form = '';\r\n\r\n self.InitialiseModule = function ($form) {\r\n var motCheckerDOMLocation;\r\n var parentDiv = $('.box--simple');\r\n var motCheckerSelecter = '.mot-checker';\r\n $.each(parentDiv, function (i, elem) {\r\n if ($(elem).find(motCheckerSelecter)) {\r\n motCheckerDOMLocation = parentDiv[i];\r\n return false;\r\n }\r\n });\r\n if (!motCheckerDOMLocation) {\r\n motCheckerDOMLocation = motCheckerSelecter;\r\n }\r\n self.Form = $form;\r\n ko.applyBindings(self, motCheckerDOMLocation);\r\n };\r\n\r\n self.MotClass = function() {\r\n if (self.Vehicle.ValidMot()) {\r\n return ns.Constants.ValidClass;\r\n }\r\n\r\n return ns.Constants.InvalidClass;\r\n };\r\n\r\n self.ResetForm = function () {\r\n self.Vehicle.RegNumber('');\r\n self.ShowSearch(true);\r\n self.VehicleNotFound(false);\r\n self.VehicleErrorOccurred(false);\r\n };\r\n\r\n self.GetDetails = function () {\r\n var result = ns.Utils.ValidateForm(self.Form);\r\n if (result) {\r\n self.VehicleNotFound(false);\r\n self.Vehicle.RegNumber($('#regNumber').val());\r\n\r\n $.ajax({\r\n url: '/api/lookupv2/VehicleRunningDetails',\r\n contentType: 'text/json',\r\n type: 'POST',\r\n data: ko.toJSON({\r\n RegNumber: self.Vehicle.RegNumber()\r\n }),\r\n success: function(data) {\r\n var details = data;\r\n if (details != null && details.MotExpiry!==undefined) {\r\n self.Vehicle.MotExpiry(details.MotExpiry);\r\n self.Vehicle.Make(details.MakeDescription);\r\n self.Vehicle.Model(details.ModelDescription);\r\n self.VehicleNotFound(false);\r\n } else {\r\n self.Vehicle.Make('');\r\n self.Vehicle.Model('');\r\n self.VehicleNotFound(true);\r\n }\r\n\r\n self.ShowSearch(false);\r\n\r\n },\r\n error: function () {\r\n self.Vehicle.Make('');\r\n self.Vehicle.Model('');\r\n self.VehicleNotFound(true);\r\n self.VehicleErrorOccurred(true);\r\n self.ShowSearch(false);\r\n }\r\n });\r\n }\r\n };\r\n\r\n };\r\n}(CONFUSEDCMS.VehicleDetails, jQuery));\r\n","var CONFUSEDCMS = CONFUSEDCMS || {};\r\nCONFUSEDCMS.VehicleDetailsValidation = CONFUSEDCMS.VehicleDetailsValidation || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n\r\n ns.jQueryValidateExtensions = function () {\r\n\r\n //Regex Method Validator\r\n $.validator.addMethod(\r\n 'regex',\r\n function (value, element, regexp) {\r\n var re = new RegExp(regexp);\r\n return this.optional(element) || re.test(value);\r\n },\r\n 'Please check your input.'\r\n );\r\n\r\n $.validator.addMethod(\r\n 'notdefault',\r\n function (value, element, param) {\r\n var $element = jQuery(element);\r\n\r\n if ($element.is('[type=checkbox]')) {\r\n return $element.is(':checked');\r\n }\r\n\r\n if ($element.is('[type=radio]')) {\r\n var checkBoxName = $element.attr('name');\r\n return $('[name=' + checkBoxName + ']').is(':checked');\r\n }\r\n\r\n if (value === param) {\r\n return false;\r\n }\r\n\r\n return true;\r\n },\r\n 'Please check your input.'\r\n );\r\n\r\n };\r\n\r\n ns.vehicleDetailsCheckerRules = function () {\r\n\r\n function addRule(validator, $form, validationRule) {\r\n var $elem = $form.find(validationRule.selector);\r\n\r\n if ($elem.length !== 0) {\r\n $elem.rules('add', validationRule.rules);\r\n }\r\n }\r\n\r\n var ValidationDefinition = function (selector, rules, message) {\r\n this.selector = selector;\r\n this.rules = rules;\r\n this.message = message;\r\n };\r\n\r\n\r\n function hookupForm($form, validators, options) {\r\n if (!$form) {\r\n throw '$form is undefined!';\r\n }\r\n\r\n //exit early if form isn't found\r\n if ($form.length === 0) {\r\n return;\r\n }\r\n options = options || {};\r\n\r\n var validator = $form.validate(options);\r\n\r\n for (var i = 0; i < validators.length; i++) {\r\n var validationRule = validators[i];\r\n addRule(validator, $form, validationRule);\r\n }\r\n }\r\n\r\n var validationRules = {\r\n \r\n VehicleReg: new ValidationDefinition('input#regNumber', {\r\n notdefault: '',\r\n regex: '^[a-zA-Z0-9 -]{2,10}$',\r\n messages: {\r\n notdefault: 'Please enter a vehicle registration number',\r\n regex: 'Please enter a valid vehicle registration number'\r\n }\r\n })\r\n };\r\n\r\n return {\r\n hookup: hookupForm,\r\n validationRules: validationRules\r\n };\r\n\r\n };\r\n\r\n CONFUSEDCMS.setUpVehicleDetailsCheckerValidation = function ($form) {\r\n ns.jQueryValidateExtensions();\r\n\r\n\r\n var vehicleDetailsCheckerRules = ns.vehicleDetailsCheckerRules();\r\n vehicleDetailsCheckerRules.hookup($form, [\r\n vehicleDetailsCheckerRules.validationRules.VehicleReg\r\n ],\r\n {\r\n errorElement: 'div',\r\n errorClass: 'error-message',\r\n errorPlacement: function (error) {\r\n $('div#error-placement').first().append(error);\r\n },\r\n onfocusout: function (element) {\r\n if ((!$(element).hasClass('ignore')) && $(element).hasClass('notdefault') || (!this.checkable(element) && (element.name in this.submitted || !this.optional(element)))) {\r\n this.element(element);\r\n }\r\n },\r\n onblur: function (element) {\r\n if ((!$(element).hasClass('ignore')) && $(element).hasClass('notdefault') || (!this.checkable(element) && (element.name in this.submitted || !this.optional(element)))) {\r\n this.element(element);\r\n }\r\n },\r\n\r\n highlight: function () {\r\n },\r\n\r\n unhighlight: function () {\r\n },\r\n\r\n ignore: ':not(\\'input#regNumber\\')'\r\n });\r\n };\r\n\r\n\r\n}(CONFUSEDCMS.VehicleDetailsValidation, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDPETROLPRICES = CONFUSEDPETROLPRICES || {},\r\n Confused = Confused || {},\r\n newrelic = newrelic || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n // html elements\r\n ns.Elements = {\r\n SFPostcode: '#sfPostcode',\r\n SFRadius: '#sfRadius',\r\n SFPostcodeError: '#sfPostcodeError',\r\n RSPostcode: '#rsPostcode',\r\n RSFuelTypeDefaultOption: '#rsFuelType option[value=\\'0\\']',\r\n RSPostcodeError: '#rsPostcodeError',\r\n ScrollPricesRightLink: '.petrol-price-results__link--right',\r\n ScrollPricesLeftLink: '.petrol-price-results__link--left',\r\n ShowingNumberOfPrices: '#showingNumberOfPrices',\r\n ShowingNumberOfPricesTokenized: '#showingNumberOfPricesTokenized',\r\n IsOpenFilter: '#open-now-check',\r\n SortPricesByCheapest: '#sortPricesByCheapest',\r\n SortPricesByDistance: '#sortPricesByDistance',\r\n PetrolPriceCalculator: 'div.petrol-price-calculator',\r\n DirectionsApiLink: '#directionsApiLink'\r\n };\r\n\r\n // css classes\r\n ns.Classes = {\r\n ResultsFilterActive: 'results-filter--active'\r\n };\r\n\r\n // constants\r\n ns.Constants = {\r\n AppleMaps: 'http://maps.apple.com/maps?',\r\n AndroidMaps: 'geo:',\r\n HttpsMaps: 'https://maps.google.com/?',\r\n IPhone: 'iPhone',\r\n IPod: 'iPod',\r\n IPad: 'iPad',\r\n Android: 'android',\r\n AuthPromptCookieName: 'AuthPrompt',\r\n PriceNumberOfDecimalPlaces: 1,\r\n DistanceNumberOfDecimalPlaces: 1,\r\n SavingsNumberOfDecimalPlaces: 2,\r\n MyLocation: 'My location',\r\n Radius5Miles: 5,\r\n Radius10Miles: 10,\r\n Radius25Miles: 25,\r\n PriceTypeMock: 3,\r\n RequestSourceShowMoreResults: 'ShowMoreResults',\r\n RequestSourceAutoSearch: 'AutoSearch',\r\n RequestSourceSearchForm: 'SearchForm',\r\n RequestSourceResultsForm: 'ResultsForm',\r\n CurrentLocationUnavailable: 'Unable to find current location',\r\n CurrentLocationError: 'Unable to find current location',\r\n Station: 'station',\r\n Stations: 'stations',\r\n PriceStatisticDefaultValue: '-',\r\n PetrolAppName: 'PetrolPrices'\r\n };\r\n\r\n // tokens\r\n ns.Tokens = {\r\n NumberOfPrices: '[#NumberOfPrices]'\r\n };\r\n\r\n // utils functions\r\n ns.Utils = {\r\n\r\n // bind json price to model\r\n BindPrice: function (price, jsonPrice) {\r\n price.CategoryNumber(jsonPrice.CategoryNumber);\r\n price.Brand(jsonPrice.Brand);\r\n price.SiteName(jsonPrice.SiteName);\r\n price.Street(jsonPrice.Street);\r\n price.Suburb(jsonPrice.Suburb);\r\n price.Town(jsonPrice.Town);\r\n price.County(jsonPrice.County);\r\n price.Postcode(jsonPrice.Postcode);\r\n price.FormattedAddress(jsonPrice.FormattedAddress);\r\n price.Longitude(jsonPrice.Longitude);\r\n price.Latitude(jsonPrice.Latitude);\r\n price.FuelTypeId(jsonPrice.FuelTypeId);\r\n price.DateOfPrice(ns.Utils.FormatDateOfPrice(jsonPrice.DateOfPrice));\r\n price.ModalPrice(jsonPrice.ModalPrice.toFixed(ns.Constants.PriceNumberOfDecimalPlaces));\r\n price.Distance(jsonPrice.Distance.toFixed(ns.Constants.DistanceNumberOfDecimalPlaces));\r\n price.Logo(jsonPrice.Logo);\r\n price.Savings(jsonPrice.Savings.toFixed(ns.Constants.SavingsNumberOfDecimalPlaces));\r\n price.Ranking(jsonPrice.Ranking);\r\n price.OpeningTime(jsonPrice.OpeningTime);\r\n price.ClosingTime(jsonPrice.ClosingTime);\r\n price.Fuel24Hours(jsonPrice.Fuel24Hours);\r\n price.AutomatService(jsonPrice.AutomatService);\r\n price.IsOpen(jsonPrice.IsOpen);\r\n price.IsOpenText(jsonPrice.IsOpenText);\r\n price.OpeningClosingTimeText(jsonPrice.OpeningClosingTimeText);\r\n price.OpeningHoursText(jsonPrice.OpeningHoursText);\r\n price.PriceType(jsonPrice.PriceType);\r\n price.Enabled(true);\r\n },\r\n\r\n // format date of price\r\n FormatDateOfPrice: function (dateOfPrice) {\r\n var date = new Date(Date.parse(dateOfPrice));\r\n\r\n var day = date.getDate();\r\n var month = $.datepicker.formatDate('MM', date);\r\n var year = date.getFullYear();\r\n\r\n return day + ' ' + month + ' ' + year;\r\n },\r\n\r\n // sort prices by cheapest\r\n SortPricesByCheapest: function (self) {\r\n self.Prices.sort(function (left, right) {\r\n var leftModalPrice = parseFloat(left.ModalPrice());\r\n var rightModalPrice = parseFloat(right.ModalPrice());\r\n\r\n return leftModalPrice === rightModalPrice ? 0 : (leftModalPrice < rightModalPrice ? - 1 : 1);\r\n });\r\n\r\n // scrollable prices\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender(self.countNumberOfPrices());\r\n },\r\n\r\n // sort prices by distance\r\n SortPricesByDistance: function (self) {\r\n self.Prices.sort(function (left, right) {\r\n var leftDistance = parseFloat(left.Distance());\r\n var rightDistance = parseFloat(right.Distance());\r\n\r\n return leftDistance === rightDistance ? 0 : (leftDistance < rightDistance ? -1 : 1);\r\n });\r\n\r\n // scrollable prices\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender(self.countNumberOfPrices());\r\n },\r\n\r\n // format price statistic\r\n FormatPriceStatistic : function (priceStatistic) {\r\n\r\n if (!priceStatistic) {\r\n return ns.Constants.PriceStatisticDefaultValue;\r\n }\r\n\r\n return priceStatistic;\r\n },\r\n\r\n // write new relic event\r\n WriteNewRelicPageEvent: function(eventName, eventArgs) {\r\n eventArgs = eventArgs || { };\r\n eventArgs = ns.Utils.GetCustomerFromCookies(eventArgs);\r\n if (newrelic && newrelic.addPageAction !== undefined){\r\n newrelic.addPageAction(CONFUSEDPETROLPRICES.Constants.PetrolAppName + eventName, eventArgs);\r\n }\r\n },\r\n\r\n // get customer from cookies\r\n GetCustomerFromCookies: function(object) {\r\n object = object || {};\r\n var cookies = document.cookie.split(';'),\r\n xUniqueCustomerSessionIdString = 'X-UniqueCustomerSessionID',\r\n xUniqueCustomerCookieIdString = 'X-UniqueCustomerCookieID',\r\n xUniqueCustomerSessionId = '',\r\n xUniqueCustomerCookieId = '';\r\n\r\n for (var c = 0; c < cookies.length; c++) {\r\n if (cookies[c].indexOf(xUniqueCustomerSessionIdString) !== -1) {\r\n xUniqueCustomerSessionId = cookies[c].split('=')[1];\r\n }\r\n if (cookies[c].indexOf(xUniqueCustomerCookieIdString) !== -1){\r\n xUniqueCustomerCookieId = cookies[c].split('=')[1];\r\n }\r\n }\r\n\r\n object.XUniqueCustomerSessionIDString = xUniqueCustomerSessionId;\r\n object.XUniqueCustomerCookieIDString = xUniqueCustomerCookieId;\r\n return object;\r\n }\r\n\r\n };\r\n\r\n // blank price\r\n ns.Price = function () {\r\n var self = this;\r\n self.CategoryNumber = ko.observable('');\r\n self.Brand = ko.observable('');\r\n self.SiteName = ko.observable('');\r\n self.Street = ko.observable('');\r\n self.Suburb = ko.observable('');\r\n self.Town = ko.observable('');\r\n self.County = ko.observable('');\r\n self.Postcode = ko.observable('');\r\n self.FormattedAddress = ko.observable('');\r\n self.Latitude = ko.observable('');\r\n self.Longitude = ko.observable('');\r\n self.FuelTypeId = ko.observable(0);\r\n self.DateOfPrice = ko.observable('');\r\n self.ModalPrice = ko.observable(0.0);\r\n self.Distance = ko.observable(0);\r\n self.Logo = ko.observable('');\r\n self.Savings = ko.observable(0.0);\r\n self.Ranking = ko.observable(0);\r\n self.OpeningTime = ko.observable('');\r\n self.ClosingTime = ko.observable('');\r\n self.Fuel24Hours = ko.observable('');\r\n self.AutomatService = ko.observable('');\r\n self.IsOpen = ko.observable('');\r\n self.IsOpenText = ko.observable('');\r\n self.OpeningClosingTimeText = ko.observable('');\r\n self.OpeningHoursText = ko.observable('');\r\n self.PriceType = ko.observable(0);\r\n self.Enabled = ko.observable(true);\r\n };\r\n\r\n // petrol prices functions\r\n ns.PetrolPricesForm = function () {\r\n var self = this;\r\n self.currentStep = ko.observable(1);\r\n self.currentFilter = ko.observable(0);\r\n self.currentHeader = ko.observable(0);\r\n self.currentRadiusSearch = ko.observable(0);\r\n self.currentLogin = ko.observable(0);\r\n self.currentNotificationBar = ko.observable(0);\r\n self.currentNoPrices = ko.observable(0);\r\n self.currentPriceListError = ko.observable(0);\r\n self.currentNotificationPanel = ko.observable(0);\r\n self.FuelType = ko.observable('');\r\n self.Radius = ko.observable('');\r\n self.Postcode = ko.observable('');\r\n self.PostcodeLatitude = ko.observable(0);\r\n self.PostcodeLongitude = ko.observable(0);\r\n self.Prices = new ko.observableArray();\r\n self.DirectionsMap = '';\r\n self.DirectionsRenderer = '';\r\n self.PetrolHighest = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.PetrolLowest = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.PetrolAverage = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.PetrolLastUpdated = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.DieselHighest = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.DieselLowest = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.DieselAverage = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.DieselLastUpdated = ko.observable(ns.Constants.PriceStatisticDefaultValue);\r\n self.ModalOpeningHoursText = ko.observable('');\r\n self.ModalOpeningHoursAutomatService = ko.observable(false);\r\n self.NumberOfPricesWithin5Miles = ko.observable(0);\r\n self.NumberOfPricesWithin10Miles = ko.observable(0);\r\n self.NumberOfPricesWithin25Miles = ko.observable(0);\r\n self.IsAuthenticatedUser = ko.observable(false);\r\n self.IsSearching = ko.observable(false);\r\n\r\n // initialise form\r\n self.Initialise = function () {\r\n\r\n // bind to knockout\r\n ko.applyBindings(self, document.getElementById('main'));\r\n\r\n // init on page load\r\n self.initOnPageLoad();\r\n };\r\n\r\n // search form 'get prices' button\r\n self.getPrices = function (requestSource) {\r\n\r\n // ensure safari on mac yielding postcode\r\n if (CONFUSEDPETROLPRICES.isSafariOnMac()) {\r\n self.Postcode($(ns.Elements.SFPostcode).val());\r\n }\r\n\r\n // obtain form values\r\n var fuelType = self.FuelType();\r\n var radius = self.Radius();\r\n var postcode = self.Postcode();\r\n var postcodeLatitude = self.PostcodeLatitude();\r\n var postcodeLongitude = self.PostcodeLongitude();\r\n\r\n // validate form\r\n if (CONFUSEDPETROLPRICES.validateSearchForm(fuelType, radius, postcode, postcodeLatitude, postcodeLongitude) === false) {\r\n return;\r\n }\r\n\r\n // remove default '0' option from fuel type dropdown\r\n $(ns.Elements.RSFuelTypeDefaultOption).remove();\r\n\r\n // handle search form to prices\r\n CONFUSEDPETROLPRICES.searchFormToPrices();\r\n\r\n // get price list\r\n self.GetPriceList(fuelType, radius, postcode, postcodeLatitude, postcodeLongitude, requestSource);\r\n return;\r\n };\r\n\r\n // use current location lat/lng\r\n self.useCurrentLocation = function () {\r\n\r\n function processGeolocation(position) {\r\n CONFUSEDPETROLPRICES.Utils.WriteNewRelicPageEvent('CurrentPosition');\r\n\r\n // get directions api link\r\n var directionsApiLink = $(ns.Elements.DirectionsApiLink);\r\n if (directionsApiLink.length === 0) {\r\n self.handleCurrentLocationFault(ns.Constants.CurrentLocationError);\r\n return;\r\n }\r\n\r\n var directionsApiLinkValue = directionsApiLink.val();\r\n\r\n // if directions api link available, use it to get script\r\n if (directionsApiLinkValue) {\r\n\r\n $.ajax({\r\n type: 'GET',\r\n url: directionsApiLinkValue,\r\n dataType: 'script',\r\n cache: true,\r\n success: function () {\r\n\r\n // clear directions api link once script retrieved\r\n $(ns.Elements.DirectionsApiLink).val('');\r\n\r\n // obtain address\r\n self.obtainCurrentLocationAddress(position.coords.latitude, position.coords.longitude);\r\n }\r\n });\r\n } else {\r\n\r\n // obtain address\r\n self.obtainCurrentLocationAddress(position.coords.latitude, position.coords.longitude);\r\n }\r\n }\r\n\r\n function geolocationError() {\r\n CONFUSEDPETROLPRICES.Utils.WriteNewRelicPageEvent('CurrentPositionFailed');\r\n\r\n // confirm postcode not already updated with My Location\r\n if (self.Postcode() === ns.Constants.MyLocation) {\r\n return;\r\n }\r\n\r\n self.handleCurrentLocationFault(ns.Constants.CurrentLocationError);\r\n }\r\n\r\n if (navigator.geolocation) {\r\n navigator.geolocation.getCurrentPosition(\r\n processGeolocation,\r\n geolocationError,\r\n {\r\n timeout: 5000,\r\n enableHighAccuracy: true,\r\n maximumAge: 0\r\n });\r\n } else {\r\n CONFUSEDPETROLPRICES.Utils.WriteNewRelicPageEvent('CurrentPositionUnavailable');\r\n self.handleCurrentLocationFault(ns.Constants.CurrentLocationUnavailable);\r\n }\r\n\r\n return false;\r\n };\r\n\r\n // obtain current location address\r\n self.obtainCurrentLocationAddress = function (lat, lng) {\r\n\r\n // set up Google Geocoder\r\n var geocoder = new google.maps.Geocoder();\r\n\r\n // handle reverse geocoding\r\n geocoder.geocode({ 'location': { lat: parseFloat(lat), lng: parseFloat(lng) } }, function (results, status) {\r\n\r\n var placePostcode = null;\r\n if (status === 'OK' && results[0]) {\r\n\r\n // loop through results\r\n $.each(results, function () {\r\n\r\n var place = this;\r\n if (place.address_components !== null && place.address_components !== undefined) {\r\n\r\n // obtain postcode\r\n $.each(place.address_components, function () {\r\n if (this.types[0] &&\r\n this.types[0] === 'postal_code' &&\r\n this.types[0].replace(/\\s/g, '').length > 4) {\r\n\r\n placePostcode = this.short_name;\r\n return false;\r\n }\r\n });\r\n }\r\n\r\n if (placePostcode !== null) {\r\n return false;\r\n }\r\n });\r\n }\r\n\r\n // update postcode field\r\n if (placePostcode !== null) {\r\n self.Postcode(placePostcode);\r\n CONFUSEDPETROLPRICES.submitPageEvent({ EventType: 'petrolprices:currentlocation:geocoder', EventInfo: { 'Status': 'Postcode retrieved: ' + placePostcode } });\r\n CONFUSEDPETROLPRICES.Utils.WriteNewRelicPageEvent('GeocoderPostcodeRetrieved');\r\n } else {\r\n self.Postcode(ns.Constants.MyLocation);\r\n self.PostcodeLatitude(lat);\r\n self.PostcodeLongitude(lng);\r\n CONFUSEDPETROLPRICES.submitPageEvent({ EventType: 'petrolprices:currentlocation:geocoder', EventInfo: { 'Status': 'Postcode not retrieved' } });\r\n CONFUSEDPETROLPRICES.Utils.WriteNewRelicPageEvent('GeocoderPostcodeNotRetrieved');\r\n }\r\n\r\n // clear postcode validation\r\n $(ns.Elements.SFPostcodeError).html('');\r\n $(ns.Elements.SFPostcodeError).hide();\r\n\r\n $(ns.Elements.RSPostcodeError).html('');\r\n $(ns.Elements.RSPostcodeError).hide();\r\n });\r\n };\r\n\r\n // handle current location fault\r\n self.handleCurrentLocationFault = function (faultMessage) {\r\n if (self.currentStep() === 1) {\r\n $(ns.Elements.SFPostcodeError).html(faultMessage);\r\n $(ns.Elements.SFPostcodeError).show();\r\n } else {\r\n $(ns.Elements.RSPostcodeError).html(faultMessage);\r\n $(ns.Elements.RSPostcodeError).show();\r\n }\r\n };\r\n\r\n // filter 'get prices by radius' button\r\n self.getPricesByRadius = function (requestSource) {\r\n\r\n // ensure safari on mac yielding postcode\r\n if(CONFUSEDPETROLPRICES.isSafariOnMac()) {\r\n self.Postcode($(ns.Elements.RSPostcode).val());\r\n }\r\n\r\n // obtain form values\r\n var fuelType = self.FuelType();\r\n var radius = self.Radius();\r\n var postcode = self.Postcode();\r\n var postcodeLatitude = self.PostcodeLatitude();\r\n var postcodeLongitude = self.PostcodeLongitude();\r\n\r\n // validate form\r\n if (CONFUSEDPETROLPRICES.validateRadiusSearch(fuelType, radius, postcode, postcodeLatitude, postcodeLongitude) === false) {\r\n return false;\r\n }\r\n\r\n // get price list\r\n self.GetPriceList(fuelType, radius, postcode, postcodeLatitude, postcodeLongitude, requestSource);\r\n return false;\r\n };\r\n\r\n self.getDomain = function() {\r\n if (self._getDomain === undefined) {\r\n var hostNameArray = window.location.hostname.split('.');\r\n var hostName = '';\r\n for (var i = 1; i < hostNameArray.length; i++)\r\n {\r\n hostName = hostName.concat('.' + hostNameArray[i]);\r\n }\r\n self._getDomain = hostName;\r\n }\r\n return self._getDomain;\r\n };\r\n\r\n // request prices\r\n self.GetPriceList = function (fuelType, radius, postcode, postcodeLatitude, postcodeLongitude, requestSource) {\r\n\r\n // if unathenticated user\r\n var unauthenticatedUserPricesNumberOfRequests = 0;\r\n if (self.IsAuthenticatedUser() === false) {\r\n\r\n // get state via auth prompt cookie (create cookie if not present) \r\n if (Confused.CookieManager.prototype.hasItem(ns.Constants.AuthPromptCookieName)) {\r\n var authPromptCookieValue = Confused.CookieManager.prototype.getItem(ns.Constants.AuthPromptCookieName);\r\n unauthenticatedUserPricesNumberOfRequests = authPromptCookieValue.split(',')[0];\r\n } else {\r\n Confused.CookieManager.prototype.setItem(ns.Constants.AuthPromptCookieName, '0,,', null, '/', self.getDomain());\r\n }\r\n }\r\n\r\n // only send lat/lng if 'My location'\r\n if (postcode !== ns.Constants.MyLocation) {\r\n postcodeLatitude = null;\r\n postcodeLongitude = null;\r\n }\r\n\r\n // hide results panel border\r\n CONFUSEDPETROLPRICES.hideResultsPanelBorder();\r\n\r\n // hide opening hours modal\r\n CONFUSEDPETROLPRICES.openingHoursModalCloseClick();\r\n\r\n // disable postcode error\r\n CONFUSEDPETROLPRICES.disablePostcodeError();\r\n\r\n // display 'please wait...'\r\n self.currentStep(8);\r\n\r\n // enable 'is searching'\r\n if (self.IsSearching()) {\r\n return;\r\n }\r\n self.IsSearching(true);\r\n\r\n // make ajax request for prices\r\n $.ajax({\r\n url: '/api/petrolv2/petrolprices/GetPriceList',\r\n data: ko.toJSON({\r\n FuelType: fuelType, Radius: radius, Postcode: postcode, PostcodeLatitude: postcodeLatitude,\r\n PostcodeLongitude: postcodeLongitude, UnauthenticatedUserPricesNumberOfRequests: unauthenticatedUserPricesNumberOfRequests,\r\n RequestSource: requestSource\r\n }),\r\n type: 'POST',\r\n contentType: 'text/json',\r\n success: function (priceList) {\r\n\r\n // disable 'is searching'\r\n self.IsSearching(false);\r\n\r\n // handle retrieved price list\r\n self.handleRetrievedPriceList(priceList);\r\n },\r\n error: function () {\r\n\r\n // disable 'is searching'\r\n self.IsSearching(false);\r\n\r\n // handle retrieved price list error\r\n self.handleRetrievedPriceListError();\r\n },\r\n timeout: 20000\r\n });\r\n };\r\n\r\n // request price statistics\r\n self.GetPriceStatistics = function () {\r\n\r\n // make ajax request for prices\r\n $.ajax({\r\n url: '/api/petrolv2/petrolprices/GetPriceStatistics',\r\n data: ko.toJSON({}),\r\n type: 'POST',\r\n contentType: 'text/json',\r\n success: function (priceStatistics) {\r\n\r\n if (priceStatistics == null || priceStatistics.PetrolLastUpdated == null) {\r\n return;\r\n }\r\n\r\n // set price statistics\r\n self.PetrolHighest(ns.Utils.FormatPriceStatistic(priceStatistics.PetrolHighest));\r\n self.PetrolLowest(ns.Utils.FormatPriceStatistic(priceStatistics.PetrolLowest));\r\n self.PetrolAverage(ns.Utils.FormatPriceStatistic(priceStatistics.PetrolAverage));\r\n self.PetrolLastUpdated(ns.Utils.FormatPriceStatistic(priceStatistics.PetrolLastUpdated));\r\n self.DieselHighest(ns.Utils.FormatPriceStatistic(priceStatistics.DieselHighest));\r\n self.DieselLowest(ns.Utils.FormatPriceStatistic(priceStatistics.DieselLowest));\r\n self.DieselAverage(ns.Utils.FormatPriceStatistic(priceStatistics.DieselAverage));\r\n self.DieselLastUpdated(ns.Utils.FormatPriceStatistic(priceStatistics.DieselLastUpdated));\r\n\r\n // set authentication state\r\n self.IsAuthenticatedUser(priceStatistics.IsAuthenticatedUser);\r\n },\r\n error: function () {\r\n },\r\n timeout: 20000\r\n });\r\n };\r\n\r\n\r\n\r\n // handle retrieved price list\r\n self.handleRetrievedPriceList = function (priceList) {\r\n\r\n // 1. if error\r\n if (priceList.result === false) {\r\n self.handleRetrievedPriceListError();\r\n return;\r\n }\r\n\r\n // update authentication state\r\n self.IsAuthenticatedUser(priceList.IsAuthenticatedUser);\r\n\r\n // bind postcode lat/lgn\r\n self.PostcodeLatitude(priceList.PostcodeLatitude);\r\n self.PostcodeLongitude(priceList.PostcodeLongitude);\r\n\r\n // bind number of prices within radius\r\n self.NumberOfPricesWithin5Miles(priceList.NumberOfPricesWithin5Miles);\r\n self.NumberOfPricesWithin10Miles(priceList.NumberOfPricesWithin10Miles);\r\n self.NumberOfPricesWithin25Miles(priceList.NumberOfPricesWithin25Miles);\r\n\r\n // ensure open now filter unchecked\r\n $(ns.Elements.IsOpenFilter).attr('checked', false);\r\n\r\n // if authenticated user\r\n if (self.IsAuthenticatedUser()) {\r\n\r\n // remove auth prompt cookie, if present\r\n if (Confused.CookieManager.prototype.hasItem(ns.Constants.AuthPromptCookieName)) {\r\n Confused.CookieManager.prototype.removeItem(ns.Constants.AuthPromptCookieName, '/', self.getDomain());\r\n }\r\n\r\n // 2. if capped (without prices)\r\n if (priceList.IsAuthenticatedUserPricesRequestsCapped === true) {\r\n\r\n // do not display filter\r\n self.currentFilter(0);\r\n\r\n // display 'notification' header\r\n self.currentHeader(3);\r\n\r\n // display 'searches used up' notification bar\r\n self.currentNotificationBar(1);\r\n\r\n // display 'notification panel' step\r\n self.currentStep(7);\r\n\r\n // display 'authenticated user searches used up' notification panel\r\n self.currentNotificationPanel(1);\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices(0);\r\n }\r\n\r\n // 3. if postcode not found\r\n else if (priceList.PostcodeLatitude === 0 || priceList.PostcodeLongitude === 0) {\r\n\r\n // do not display filter\r\n self.currentFilter(0);\r\n\r\n // display 'radius search' header\r\n self.currentHeader(1);\r\n\r\n // display 'stations' radius search\r\n self.currentRadiusSearch(1);\r\n\r\n // display 'notification panel' step\r\n self.currentStep(7);\r\n\r\n // display 'authenticated user postcode not found' notification panel\r\n self.currentNotificationPanel(4);\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices(0);\r\n }\r\n\r\n // 4. if no prices\r\n else if (jQuery.isEmptyObject(priceList.JsonViewPrices)) {\r\n\r\n // do not display filter\r\n self.currentFilter(0);\r\n\r\n // display 'radius search' header\r\n self.currentHeader(1);\r\n\r\n // display 'stations' radius search\r\n self.currentRadiusSearch(1);\r\n\r\n // display 'no prices' step\r\n self.currentStep(4);\r\n\r\n // display 'authenticated user' no prices\r\n self.currentNoPrices(1);\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices(0);\r\n }\r\n\r\n // 5. if cap notification (with prices)\r\n else if (priceList.AuthenticatedUserPricesRequestsRemaining === 0) {\r\n\r\n // display filter\r\n self.currentFilter(1);\r\n\r\n // display 'notification' header\r\n self.currentHeader(3);\r\n\r\n // display 'last search used up' notification bar\r\n self.currentNotificationBar(2);\r\n\r\n // display 'price list' step\r\n self.currentStep(2);\r\n\r\n // handle retrieved prices\r\n self.handleRetrievedPrices(priceList.JsonViewPrices);\r\n }\r\n\r\n // 6. otherwise prices\r\n else {\r\n\r\n // display filter\r\n self.currentFilter(1);\r\n\r\n // display 'radius search' header\r\n self.currentHeader(1);\r\n\r\n // display 'stations' radius search\r\n self.currentRadiusSearch(1);\r\n\r\n // display 'price list' step\r\n self.currentStep(2);\r\n\r\n // handle retrieved prices\r\n self.handleRetrievedPrices(priceList.JsonViewPrices);\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices(self.countNumberOfPricesExcludingMock());\r\n }\r\n }\r\n\r\n // if unauthenticated user\r\n else {\r\n\r\n // display 'login' header\r\n self.currentHeader(2);\r\n\r\n // 2. if capped (without prices)\r\n if (priceList.IsUnauthenticatedUserPricesRequestsCapped === true) {\r\n\r\n // display 'searches used up' login\r\n self.currentLogin(1);\r\n\r\n // display 'notification panel' step\r\n self.currentStep(7);\r\n\r\n // display 'unauthenticated user searches used up' notification panel\r\n self.currentNotificationPanel(2);\r\n }\r\n\r\n // 3. if postcode not found\r\n else if (priceList.PostcodeLatitude === 0 || priceList.PostcodeLongitude === 0) {\r\n\r\n // display 'postcode not found' login\r\n self.currentLogin(4);\r\n\r\n // display 'notification panel' step\r\n self.currentStep(7);\r\n\r\n // display 'unauthenticated user postcode not found' notification panel\r\n self.currentNotificationPanel(5);\r\n }\r\n\r\n // 4. if no prices\r\n else if (jQuery.isEmptyObject(priceList.JsonViewPrices)) {\r\n\r\n // display 'no prices' login\r\n self.currentLogin(3);\r\n\r\n // display 'no prices' step\r\n self.currentStep(4);\r\n\r\n // display 'unauthenticated user' no prices\r\n self.currentNoPrices(2);\r\n }\r\n\r\n // 5. otherwise prices (update state via auth prompt cookie)\r\n else {\r\n\r\n // update auth prompt cookie (state, fuel type and postcode)\r\n var unauthenticatedUserPricesNumberOfRequests = 0;\r\n\r\n if (Confused.CookieManager.prototype.hasItem(ns.Constants.AuthPromptCookieName)) {\r\n var authPromptCookieValue = Confused.CookieManager.prototype.getItem(ns.Constants.AuthPromptCookieName);\r\n unauthenticatedUserPricesNumberOfRequests = parseInt(authPromptCookieValue.split(',')[0]);\r\n }\r\n\r\n unauthenticatedUserPricesNumberOfRequests++;\r\n\r\n var authPromptCookieUpdatedValue = unauthenticatedUserPricesNumberOfRequests + ',' + self.FuelType() + ',' + self.Postcode();\r\n Confused.CookieManager.prototype.setItem(ns.Constants.AuthPromptCookieName, authPromptCookieUpdatedValue, null, '/', self.getDomain());\r\n\r\n // display 'searches used up' login\r\n self.currentLogin(1);\r\n\r\n // display 'price list' step\r\n self.currentStep(2);\r\n\r\n // handle retrieved prices\r\n self.handleRetrievedPrices(priceList.JsonViewPrices);\r\n }\r\n }\r\n\r\n return;\r\n };\r\n\r\n // handle retrieved price list\r\n self.handleRetrievedPriceListError = function () {\r\n\r\n // if authenticated user (prior to request for prices)\r\n if (self.IsAuthenticatedUser()) {\r\n\r\n // do not display filter\r\n self.currentFilter(0);\r\n\r\n // display 'radius search' header\r\n self.currentHeader(1);\r\n\r\n // display 'stations' radius search\r\n self.currentRadiusSearch(1);\r\n\r\n // display 'price list error' step\r\n self.currentStep(5);\r\n\r\n // display 'authenticated user' price list error\r\n self.currentPriceListError(1);\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices(0);\r\n\r\n // if unauthenticated user (prior to request for prices)\r\n } else {\r\n\r\n // display 'login' header\r\n self.currentHeader(2);\r\n\r\n // display 'on error' login\r\n self.currentLogin(2);\r\n\r\n // display 'price list error' step\r\n self.currentStep(5);\r\n\r\n // display 'unauthenticated user' price list error\r\n self.currentPriceListError(2);\r\n }\r\n };\r\n\r\n // handle retrieved prices\r\n self.handleRetrievedPrices = function (prices) {\r\n\r\n // show results panel border\r\n CONFUSEDPETROLPRICES.showResultsPanelBorder();\r\n\r\n // clear existing prices\r\n self.Prices.removeAll();\r\n\r\n // bind retrieved prices\r\n $.each(prices, function (index, price) {\r\n if (price !== false) {\r\n var modelPrice = new ns.Price();\r\n\r\n var jsonPrice = $.parseJSON(price);\r\n ns.Utils.BindPrice(modelPrice, jsonPrice);\r\n\r\n self.Prices.push(modelPrice);\r\n }\r\n });\r\n\r\n // sort by cheapest price\r\n self.sortPricesByCheapest();\r\n\r\n // scrollable prices on load\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender(self.countNumberOfPrices());\r\n };\r\n\r\n // get embedded map directions to petrol station\r\n self.getDirections = function (stationLatitude, stationLongitude) {\r\n\r\n // get directions api link\r\n var directionsApiLink = $(ns.Elements.DirectionsApiLink);\r\n if (directionsApiLink.length === 0) {\r\n return;\r\n }\r\n\r\n var directionsApiLinkValue = directionsApiLink.val();\r\n\r\n // if directions api link available, use it to get script\r\n if (directionsApiLinkValue) {\r\n\r\n $.ajax({\r\n type: 'GET',\r\n url: directionsApiLinkValue,\r\n dataType: 'script',\r\n cache: true,\r\n success: function () {\r\n\r\n // clear directions api link once script retrieved\r\n $(ns.Elements.DirectionsApiLink).val('');\r\n\r\n // handle directions\r\n self.handleDirections(stationLatitude, stationLongitude);\r\n }\r\n });\r\n } else {\r\n\r\n // handle directions\r\n self.handleDirections(stationLatitude, stationLongitude);\r\n }\r\n };\r\n\r\n // handle embedded map directions to petrol station\r\n self.handleDirections = function (stationLatitude, stationLongitude) {\r\n\r\n // make ajax request for whether directions enabled\r\n $.ajax({\r\n url: '/api/petrolv2/petrolprices/IsDirectionsEnabled',\r\n data: ko.toJSON({}),\r\n type: 'POST',\r\n contentType: 'text/json',\r\n success: function (directions) {\r\n\r\n // if error\r\n if (directions.result === false) {\r\n self.handleRetrievedDirectionsError();\r\n return;\r\n }\r\n\r\n // if directions enabled\r\n if (directions.IsEnabled) {\r\n\r\n // handle prices form to directions\r\n CONFUSEDPETROLPRICES.pricesFormToDirections();\r\n\r\n // render map\r\n if (self.DirectionsMap === '') {\r\n self.DirectionsMap = CONFUSEDPETROLPRICES.initDirectionsMap();\r\n }\r\n\r\n if (self.DirectionsRenderer === '') {\r\n self.DirectionsRenderer = CONFUSEDPETROLPRICES.initDirectionsRenderer();\r\n }\r\n\r\n CONFUSEDPETROLPRICES.renderDirections(\r\n self.PostcodeLatitude(),\r\n self.PostcodeLongitude(),\r\n stationLatitude(),\r\n stationLongitude(),\r\n self.DirectionsMap,\r\n self.DirectionsRenderer);\r\n\r\n // hide filter\r\n self.currentFilter(0);\r\n\r\n // display 'close map' radius search\r\n self.currentRadiusSearch(2);\r\n\r\n // display 'directions' step\r\n self.currentStep(3);\r\n\r\n // if directions not enabled\r\n } else {\r\n\r\n // hide filter\r\n self.currentFilter(0);\r\n\r\n // display 'close map' radius search\r\n self.currentRadiusSearch(2);\r\n\r\n // display 'notification panel' step\r\n self.currentStep(7);\r\n\r\n // display 'directions used up' notification panel\r\n self.currentNotificationPanel(3);\r\n }\r\n },\r\n error: function () {\r\n self.handleRetrievedDirectionsError();\r\n },\r\n timeout: 20000\r\n });\r\n\r\n };\r\n\r\n // handle retrieved directions error\r\n self.handleRetrievedDirectionsError = function () {\r\n\r\n // hide filter\r\n self.currentFilter(0);\r\n\r\n // display 'close map' radius search\r\n self.currentRadiusSearch(2);\r\n\r\n // display 'directions error' step\r\n self.currentStep(6);\r\n };\r\n\r\n // tab google map for directions to petrol station\r\n self.getTabbedDirections = function (stationLatitude, stationLongitude) {\r\n\r\n // construct maps querystring\r\n var mapsQueryString =\r\n 'saddr=' + self.PostcodeLatitude() + ',' + self.PostcodeLongitude() +\r\n '&daddr=' + stationLatitude() + ',' + stationLongitude();\r\n\r\n // open map in suitable device\r\n var win;\r\n var mapsUrl;\r\n if ((navigator.platform.indexOf(ns.Constants.IPhone) !== -1) ||\r\n (navigator.platform.indexOf(ns.Constants.IPod) !== -1) ||\r\n (navigator.platform.indexOf(ns.Constants.IPad) !== -1)) {\r\n\r\n mapsUrl = ns.Constants.AppleMaps + mapsQueryString;\r\n win = window.open(mapsUrl, '_system');\r\n } else if (navigator.platform.indexOf(ns.Constants.Android) !== -1) {\r\n\r\n mapsUrl = ns.Constants.AndroidMaps + mapsQueryString;\r\n win = window.open(mapsUrl);\r\n } else {\r\n\r\n mapsUrl = ns.Constants.HttpsMaps + mapsQueryString;\r\n win = window.open(mapsUrl, '_blank');\r\n }\r\n\r\n // confirm map opened okay\r\n if (win) {\r\n\r\n // log tabbed directions map 'permitted'\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:tabbeddirections:permitted', EventInfo: { 'MapsUrl': mapsUrl }\r\n });\r\n\r\n win.focus();\r\n } else {\r\n\r\n // log tabbed directions map 'not permitted'\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:tabbeddirections:notpermitted', EventInfo: { 'MapsUrl': mapsUrl }\r\n });\r\n }\r\n };\r\n\r\n // show opening hours modal\r\n self.showOpeningHours = function (openingHoursText, automatService) {\r\n self.ModalOpeningHoursText(openingHoursText());\r\n self.ModalOpeningHoursAutomatService(automatService);\r\n CONFUSEDPETROLPRICES.openingHoursLinkClick();\r\n\r\n // log 'show opening hours' click\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:openinghours:show', EventInfo: {}\r\n });\r\n };\r\n\r\n // close opening hours modal\r\n self.closeOpeningHours = function () {\r\n self.ModalOpeningHoursText('');\r\n self.ModalOpeningHoursAutomatService(false);\r\n CONFUSEDPETROLPRICES.openingHoursModalCloseClick();\r\n };\r\n\r\n // sort by cheapest price\r\n self.sortPricesByCheapest = function () {\r\n\r\n // sort by distance then cheapest\r\n ns.Utils.SortPricesByDistance(self);\r\n ns.Utils.SortPricesByCheapest(self);\r\n\r\n // set 'sort prices by cheapest' link to active\r\n $(ns.Elements.SortPricesByCheapest).addClass(ns.Classes.ResultsFilterActive);\r\n $(ns.Elements.SortPricesByDistance).removeClass(ns.Classes.ResultsFilterActive);\r\n };\r\n\r\n // sort by closest price\r\n self.sortPricesByDistance = function () {\r\n\r\n // sort by cheapest then distance\r\n ns.Utils.SortPricesByCheapest(self);\r\n ns.Utils.SortPricesByDistance(self);\r\n\r\n // set 'sort prices by distance' link to active\r\n $(ns.Elements.SortPricesByDistance).addClass(ns.Classes.ResultsFilterActive);\r\n $(ns.Elements.SortPricesByCheapest).removeClass(ns.Classes.ResultsFilterActive);\r\n };\r\n\r\n // count number of prices (including mock prices)\r\n self.countNumberOfPrices = function () {\r\n var count = 0;\r\n\r\n $.each(self.Prices(), function (index, price) {\r\n if(price.Enabled()) {\r\n count++;\r\n }\r\n });\r\n\r\n return count;\r\n };\r\n\r\n // count number of prices (excluding mock prices)\r\n self.countNumberOfPricesExcludingMock = function () {\r\n var count = 0;\r\n\r\n $.each(self.Prices(), function (index, price) {\r\n if (price.Enabled() && (price.PriceType() !== ns.Constants.PriceTypeMock)) {\r\n count++;\r\n }\r\n });\r\n\r\n return count;\r\n };\r\n\r\n // showing number of prices\r\n self.showingNumberOfPrices = function (numberOfPrices) {\r\n\r\n // get text\r\n var showingNumberOfPricesTokenizedText = $(ns.Elements.ShowingNumberOfPricesTokenized).val();\r\n\r\n // replace token with number of prices\r\n var showingNumberOfPricesText = showingNumberOfPricesTokenizedText.replace(ns.Tokens.NumberOfPrices, numberOfPrices);\r\n\r\n // replace plural if only 1 price \r\n if (numberOfPrices === 1) {\r\n showingNumberOfPricesText = showingNumberOfPricesText.replace(ns.Constants.Stations, ns.Constants.Station);\r\n }\r\n\r\n // set text\r\n $(ns.Elements.ShowingNumberOfPrices).text(showingNumberOfPricesText);\r\n };\r\n\r\n // handle auth prompt cookie\r\n self.handleAuthPromptCookie = function () {\r\n\r\n // get fuel type and postcode\r\n var fuelType = null;\r\n var postcode = null;\r\n\r\n if (Confused.CookieManager.prototype.hasItem(ns.Constants.AuthPromptCookieName)) {\r\n var authPromptCookieValue = Confused.CookieManager.prototype.getItem(ns.Constants.AuthPromptCookieName);\r\n fuelType = parseInt(authPromptCookieValue.split(',')[1]);\r\n postcode = authPromptCookieValue.split(',')[2];\r\n }\r\n\r\n // if fuel type and postcode found...\r\n if ((fuelType != null && fuelType !== '') &&\r\n (postcode != null && postcode !== '' && postcode !== ns.Constants.MyLocation)) {\r\n\r\n // store fuel type and postcode\r\n self.FuelType(fuelType);\r\n self.Postcode(postcode);\r\n\r\n // get prices\r\n self.getPrices(ns.Constants.RequestSourceAutoSearch);\r\n }\r\n };\r\n\r\n // 'directions back to prices' button\r\n self.directionsBackToPrices = function () {\r\n // display 'price list' step\r\n self.currentStep(2);\r\n\r\n // display filter\r\n self.currentFilter(1);\r\n\r\n // display 'stations' radius search\r\n self.currentRadiusSearch(1);\r\n\r\n // handle directions form to prices\r\n CONFUSEDPETROLPRICES.directionsFormToPrices();\r\n };\r\n\r\n // 'prices back to search' button\r\n self.pricesBackToSearch = function () {\r\n\r\n // hide 'login' header\r\n self.currentHeader(0);\r\n\r\n // display 'search form' step\r\n self.currentStep(1);\r\n\r\n // handle prices form to search\r\n CONFUSEDPETROLPRICES.pricesFormToSearch();\r\n };\r\n\r\n // 'show more results' button\r\n self.showMoreResults = function () {\r\n\r\n // update to wider radius\r\n var currentRadius = parseInt(self.Radius());\r\n\r\n if (currentRadius === ns.Constants.Radius5Miles && self.NumberOfPricesWithin10Miles() > self.NumberOfPricesWithin5Miles()) {\r\n self.Radius(ns.Constants.Radius10Miles);\r\n } else if (currentRadius === ns.Constants.Radius5Miles && self.NumberOfPricesWithin25Miles() > self.NumberOfPricesWithin5Miles()) {\r\n self.Radius(ns.Constants.Radius25Miles);\r\n } else if (currentRadius === ns.Constants.Radius10Miles && self.NumberOfPricesWithin25Miles() > self.NumberOfPricesWithin10Miles()) {\r\n self.Radius(ns.Constants.Radius25Miles);\r\n }\r\n\r\n // get prices\r\n self.getPricesByRadius(ns.Constants.RequestSourceShowMoreResults);\r\n };\r\n\r\n // bind events\r\n self.bindEvents = function () {\r\n\r\n // only show prices from currently open petrol stations\r\n $(ns.Elements.IsOpenFilter).change(function () {\r\n\r\n var filterOn = $(this).is(':checked');\r\n\r\n if (filterOn) {\r\n $.each(self.Prices(), function (index, price) {\r\n if (price.IsOpen() === false) {\r\n price.Enabled(false);\r\n }\r\n });\r\n } else {\r\n $.each(self.Prices(), function (index, price) {\r\n price.Enabled(true);\r\n });\r\n }\r\n \r\n // show number of prices\r\n self.showingNumberOfPrices(self.countNumberOfPricesExcludingMock());\r\n\r\n // scrollable prices on open filter\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender(self.countNumberOfPrices());\r\n\r\n // log 'is open' click\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:filter:filterpricesbyisopen', EventInfo: { 'FilterOn': filterOn }\r\n });\r\n\r\n });\r\n\r\n // only show search form postcode section on fuel type selection\r\n $('input[type=radio][name=sfFuelType]').change(function () {\r\n CONFUSEDPETROLPRICES.showSearchFormPostcodeSection();\r\n });\r\n };\r\n\r\n // init on page load\r\n self.initOnPageLoad = function () {\r\n\r\n setTimeout(function(){\r\n\r\n // get price statistics\r\n self.GetPriceStatistics();\r\n\r\n // init MI events\r\n CONFUSEDPETROLPRICES.initEventDecorator();\r\n\r\n // init events\r\n self.bindEvents();\r\n\r\n // init validation\r\n CONFUSEDPETROLPRICES.bindValidation();\r\n\r\n // init tooltips\r\n CONFUSEDPETROLPRICES.initTooltips();\r\n\r\n // initialise opening hours\r\n CONFUSEDPETROLPRICES.initOpeningHours();\r\n\r\n // initialise internet explorer\r\n CONFUSEDPETROLPRICES.initInternetExplorer();\r\n\r\n // initialise safari\r\n CONFUSEDPETROLPRICES.initSafariOnMac();\r\n\r\n // init values\r\n self.Radius($(ns.Elements.SFRadius).val());\r\n\r\n // handle auth prompt cookie\r\n self.handleAuthPromptCookie();\r\n\r\n }, 200);\r\n };\r\n\r\n // scrollable prices on right link\r\n $(ns.Elements.ScrollPricesRightLink).click(function (e) {\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRightClick(e);\r\n });\r\n\r\n // scrollable prices on left click\r\n $(ns.Elements.ScrollPricesLeftLink).click(function (e) {\r\n CONFUSEDPETROLPRICES.scrollablePricesOnLeftClick(e);\r\n });\r\n\r\n // submit search form on postcode enter key\r\n $(ns.Elements.SFPostcode).keyup(function (e) {\r\n if (e.keyCode === 13) {\r\n self.getPrices(ns.Constants.RequestSourceSearchForm);\r\n }\r\n });\r\n\r\n // submit results form on postcode enter key\r\n $(ns.Elements.RSPostcode).keyup(function (e) {\r\n if (e.keyCode === 13) {\r\n self.getPricesByRadius(ns.Constants.RequestSourceResultsForm);\r\n }\r\n });\r\n\r\n // on window resize\r\n $(window).resize(function () {\r\n\r\n // scrollable prices on window resize\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender(self.countNumberOfPrices());\r\n });\r\n };\r\n\r\n // set up petrol prices form\r\n if ($(ns.Elements.PetrolPriceCalculator).length > 0) {\r\n var petrolPricesForm = new CONFUSEDPETROLPRICES.PetrolPricesForm();\r\n petrolPricesForm.Initialise();\r\n }\r\n\r\n})(CONFUSEDPETROLPRICES, jQuery);\r\n\r\n\r\n\r\n","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDPETROLPRICES = CONFUSEDPETROLPRICES || {};\r\nCONFUSEDPETROLPRICES.Maps = CONFUSEDPETROLPRICES.Maps || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n CONFUSEDPETROLPRICES.initDirectionsMap = function () {\r\n // initialise map\r\n return new google.maps.Map(document.getElementById('map'));\r\n };\r\n\r\n CONFUSEDPETROLPRICES.initDirectionsRenderer = function () {\r\n // initialise renderer\r\n return new google.maps.DirectionsRenderer();\r\n };\r\n\r\n CONFUSEDPETROLPRICES.renderDirections = function (postcodeLat, postcodeLng, priceLat, priceLng, map, renderer) {\r\n\r\n // set coordinates\r\n var postcodeCoord = { lat: postcodeLat, lng: postcodeLng };\r\n var stationCoord = { lat: priceLat, lng: priceLng };\r\n\r\n // set map\r\n map.setOptions({ zoom: 7, center: postcodeCoord });\r\n\r\n // set renderer\r\n renderer.setMap(map);\r\n renderer.setPanel(document.getElementById('directionsPanel'));\r\n\r\n // directions service\r\n var directionsService = new google.maps.DirectionsService();\r\n directionsService.route({\r\n origin: postcodeCoord,\r\n destination: stationCoord,\r\n travelMode: google.maps.TravelMode.DRIVING,\r\n provideRouteAlternatives: true,\r\n unitSystem: google.maps.UnitSystem.IMPERIAL\r\n }, function (response, status) {\r\n\r\n if (status === google.maps.DirectionsStatus.OK) {\r\n\r\n // log directions 'permitted'\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:directions:permitted', EventInfo: { 'Status': status }\r\n });\r\n\r\n // render\r\n renderer.setDirections(response);\r\n\r\n } else {\r\n\r\n // log directions 'not permitted'\r\n CONFUSEDPETROLPRICES.submitPageEvent({\r\n EventType: 'petrolprices:directions:notpermitted', EventInfo: { 'Status': status }\r\n });\r\n }\r\n });\r\n };\r\n\r\n}(CONFUSEDPETROLPRICES.Maps, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDPETROLPRICES = CONFUSEDPETROLPRICES || {};\r\nCONFUSEDPETROLPRICES.MiEvents = CONFUSEDPETROLPRICES.MiEvents || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n CONFUSEDPETROLPRICES.initEventDecorator = function () {\r\n\r\n // create event decorator\r\n var e = CONFUSEDCMS.eventDecorator;\r\n\r\n var functionNames = {\r\n miPageEvent: 'CONFUSEDCMS.eventDecorator.events.miPageEvent'\r\n };\r\n\r\n // add events to definition list\r\n e.EventDefinitionList.Add(new e.EventDefinition('#sortPricesByCheapest', 'click', functionNames.miPageEvent, [{ EventType: 'petrolprices:filter:sortpricesbycheapest', EventInfo: { Control: 'petrol-prices-filter' } }]));\r\n e.EventDefinitionList.Add(new e.EventDefinition('#sortPricesByDistance', 'click', functionNames.miPageEvent, [{ EventType: 'petrolprices:filter:sortpricesbydistance', EventInfo: { Control: 'petrol-prices-filter' } }]));\r\n e.EventDefinitionList.Add(new e.EventDefinition('#closeMap', 'click', functionNames.miPageEvent, [{ EventType: 'petrolprices:directions:hide', EventInfo: { Control: 'petrol-prices-directions' } }]));\r\n e.EventDefinitionList.Add(new e.EventDefinition('#petrolPricesLoginButton', 'click', functionNames.miPageEvent, [{ EventType: 'petrolprices:login:clicked', EventInfo: { Control: 'petrol-prices-login' } }]));\r\n e.EventDefinitionList.Add(new e.EventDefinition('#petrolPricesRegisterButton', 'click', functionNames.miPageEvent, [{ EventType: 'petrolprices:register:clicked', EventInfo: { Control: 'petrol-prices-login' } }]));\r\n\r\n // process all events in the definition list\r\n e.EventDefinitionList.ProcessAll();\r\n };\r\n\r\n CONFUSEDPETROLPRICES.submitPageEvent = function (eventInfo) {\r\n CONFUSEDCMS.services.MiService().pageEvent(eventInfo);\r\n };\r\n\r\n}(CONFUSEDPETROLPRICES.MiEvents, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDPETROLPRICES = CONFUSEDPETROLPRICES || {};\r\nCONFUSEDPETROLPRICES.UiElements = CONFUSEDPETROLPRICES.UiElements || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n // html elements\r\n ns.Elements = {\r\n SFFuelFinderLandingPanel: '.petrol-price-calculator__landing-panel',\r\n PRFuelFinderResultsPanel: '.petrol-price-calculator__results-panel',\r\n ScrollLeftLink: '.petrol-price-results__link--left',\r\n ScrollRightLink: '.petrol-price-results__link--right',\r\n ScrollRightBodyMarker: '.scroll-end-marker--body',\r\n ResultsUl: '.petrol-price-results',\r\n ResultsUlItems: '.petrol-price-results > li',\r\n ResultsFill: '.results-fill',\r\n PetrolPriceResultsResult: '.petrol-price-results__result',\r\n ScrollEndMarkerResult: '.scroll-end-marker--result',\r\n OpeningHoursModal: '.opening-times-modal',\r\n Dimmer: '.dimmer',\r\n ResultsPanelBody: '#resultsPanelBody',\r\n TooltipToggle: '.tooltip-toggle',\r\n TooltipWrapper: '.tooltip-wrapper',\r\n TooltipInfo: '.tooltip-info',\r\n TooltipInfoDismiss: '.tooltip-info__dismiss',\r\n ResultSectionAddress: '.petrol-price-results__result__section__address',\r\n ResultSectionLoggedOut: '.petrol-price-results__result__section--logged-out',\r\n RSCurrentLocationTooltipWrapper: '#rsCurrentLocationTooltipWrapper',\r\n RSPostcodeError: '#rsPostcodeError',\r\n RSFuelType: '#rsFuelType',\r\n RSRadius: '#rsRadius',\r\n SFPostcodeWrapper: '.postcode-wrapper',\r\n SFGetPrices: '#sfGetPrices',\r\n SFLandingPanelMainPostcode: '.petrol-price-calculator__landing-panel__main__postcode',\r\n CheapestRibbon: '.cheapest-ribbon',\r\n SortPricesByDistance: '#sortPricesByDistance'\r\n };\r\n\r\n // classes\r\n ns.Classes = {\r\n ResultsPanelBodyBorder: 'petrol-price-calculator__results-panel__body_border',\r\n OpeningHoursLinkClicked: 'opening-hours-link-clicked'\r\n };\r\n\r\n // constants\r\n ns.Constants = {\r\n Left: 'left',\r\n MarginLeft: 'margin-left',\r\n MarginRight: 'margin-right',\r\n MarginTop: 'margin-top',\r\n MarginBottom: 'margin-bottom',\r\n Pixel: 'px',\r\n Height: 'height',\r\n Open: 'open',\r\n Visible: ':visible',\r\n MaxWidth: 'max-width',\r\n Border: 'border',\r\n Disabled: 'disabled',\r\n MsIe: 'MSIE ',\r\n MsIe11: 'Trident/',\r\n Macintosh: 'Macintosh ',\r\n Safari: 'Safari',\r\n Chrome: 'Chrome',\r\n IPad: 'iPad',\r\n IPod: 'iPod',\r\n IPhone: 'iPhone',\r\n ResultWidth: 240\r\n };\r\n\r\n // utils functions\r\n ns.Utils = {\r\n\r\n // clear address height\r\n ClearAddressHeight: function () {\r\n\r\n // get all list items\r\n var listItem = $(ns.Elements.ResultsUlItems);\r\n\r\n // clear height of each address item\r\n listItem.each(function () {\r\n $(this).find(ns.Elements.ResultSectionAddress).css(ns.Constants.Height, '');\r\n });\r\n },\r\n\r\n // clear price list height\r\n ClearPriceListHeight: function () {\r\n\r\n // get all list items\r\n var listItem = $(ns.Elements.ResultsUlItems);\r\n\r\n // clear height of each list item\r\n listItem.each(function () {\r\n $(this).css(ns.Constants.Height, '');\r\n });\r\n\r\n // clear height of each logged out item\r\n listItem.each(function() {\r\n $(this).find(ns.Elements.ResultSectionLoggedOut).css(ns.Constants.Height, '');\r\n });\r\n\r\n // clear height of results fill\r\n $(ns.Elements.ResultsFill).css(ns.Constants.Height, '');\r\n\r\n // clear height of list\r\n $(ns.Elements.ResultsUl).css(ns.Constants.Height, '');\r\n\r\n // clear height of results panel\r\n $(ns.Elements.ResultsPanelBody).css(ns.Constants.Height, '');\r\n\r\n // clear height of dimmer\r\n $(ns.Elements.Dimmer).css(ns.Constants.Height, '');\r\n },\r\n\r\n // set address height\r\n SetAddressHeight: function () {\r\n\r\n // get all list items\r\n var listItem = $(ns.Elements.ResultsUlItems);\r\n\r\n // get max height of address items\r\n var maxHeight = 0;\r\n listItem.each(function () {\r\n var thisHeight = $(this).find(ns.Elements.ResultSectionAddress).outerHeight();\r\n\r\n if (thisHeight > maxHeight) {\r\n maxHeight = thisHeight;\r\n }\r\n });\r\n\r\n // ensure address items found\r\n if (maxHeight === 0) {\r\n return;\r\n }\r\n\r\n // set height of each address item\r\n listItem.each(function () {\r\n $(this).find(ns.Elements.ResultSectionAddress).css(ns.Constants.Height, maxHeight);\r\n });\r\n },\r\n\r\n // set price list height\r\n SetPriceListHeight: function () {\r\n\r\n // get all list items\r\n var listItem = $(ns.Elements.ResultsUlItems);\r\n\r\n // get max height of list items\r\n var maxHeight = 0;\r\n listItem.each(function () {\r\n var thisHeight = $(this).outerHeight();\r\n\r\n if (thisHeight > maxHeight) {\r\n maxHeight = thisHeight;\r\n }\r\n });\r\n\r\n // ensure list items found\r\n if (maxHeight === 0) {\r\n return;\r\n }\r\n\r\n // set height of each list item\r\n listItem.each(function () {\r\n $(this).css(ns.Constants.Height, maxHeight);\r\n });\r\n\r\n // set height of each logged out item\r\n var loggedOutItemHeight;\r\n if ($(window).width() > 900) {\r\n loggedOutItemHeight = maxHeight - 139;\r\n } else {\r\n loggedOutItemHeight = maxHeight - 119;\r\n }\r\n\r\n listItem.each(function() {\r\n $(this).find(ns.Elements.ResultSectionLoggedOut).css(ns.Constants.Height, loggedOutItemHeight);\r\n });\r\n\r\n // set height of results fill\r\n $(ns.Elements.ResultsFill).css(ns.Constants.Height, maxHeight);\r\n\r\n // set height of list\r\n $(ns.Elements.ResultsUl).css(ns.Constants.Height, maxHeight + 1);\r\n\r\n // set height of results panel\r\n if ($(window).width() > 600) {\r\n $(ns.Elements.ResultsPanelBody).css(ns.Constants.Height, maxHeight + 1);\r\n } else {\r\n $(ns.Elements.ResultsPanelBody).css(ns.Constants.Height, maxHeight + 21);\r\n }\r\n\r\n // set height of dimmer\r\n $(ns.Elements.Dimmer).css(ns.Constants.Height, maxHeight + 1);\r\n }\r\n };\r\n\r\n // search form to prices\r\n CONFUSEDPETROLPRICES.searchFormToPrices = function () {\r\n $(ns.Elements.SFFuelFinderLandingPanel).hide();\r\n $(ns.Elements.PRFuelFinderResultsPanel).show();\r\n };\r\n\r\n // prices form to directions\r\n CONFUSEDPETROLPRICES.pricesFormToDirections = function () {\r\n\r\n // clear price list height\r\n ns.Utils.ClearPriceListHeight();\r\n\r\n // hide results panel border\r\n CONFUSEDPETROLPRICES.hideResultsPanelBorder();\r\n };\r\n\r\n // directions form to prices\r\n CONFUSEDPETROLPRICES.directionsFormToPrices = function () {\r\n\r\n // set price list height\r\n ns.Utils.SetPriceListHeight();\r\n\r\n // show results panel border\r\n CONFUSEDPETROLPRICES.showResultsPanelBorder();\r\n };\r\n\r\n // prices form to search\r\n CONFUSEDPETROLPRICES.pricesFormToSearch = function () {\r\n $(ns.Elements.PRFuelFinderResultsPanel).hide();\r\n $(ns.Elements.SFFuelFinderLandingPanel).show();\r\n };\r\n\r\n // prices on render\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRender = function (numberOfPrices) {\r\n ns.Utils.ClearAddressHeight();\r\n ns.Utils.ClearPriceListHeight();\r\n\r\n var resultLiWidth = $(ns.Elements.PetrolPriceResultsResult).width() + 2;\r\n var pricesWidth = resultLiWidth * numberOfPrices;\r\n var pricesWidthMinusOne = resultLiWidth * (numberOfPrices - 1);\r\n\r\n if ($(window).width() > 583) {\r\n $(ns.Elements.ResultsUl).width(pricesWidthMinusOne);\r\n $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft, ns.Constants.ResultWidth);\r\n\r\n if ($(ns.Elements.PRFuelFinderResultsPanel).width() > pricesWidth) {\r\n $(ns.Elements.ScrollRightLink).hide();\r\n } else {\r\n $(ns.Elements.ScrollRightLink).show();\r\n }\r\n\r\n $(ns.Elements.ScrollLeftLink).hide();\r\n }\r\n else {\r\n $(ns.Elements.ResultsUl).width(pricesWidth);\r\n $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft, 0);\r\n $(ns.Elements.ScrollLeftLink).hide();\r\n $(ns.Elements.ScrollRightLink).hide();\r\n }\r\n\r\n ns.Utils.SetAddressHeight();\r\n ns.Utils.SetPriceListHeight();\r\n\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbonOnTimeout();\r\n };\r\n\r\n // prices on right click\r\n CONFUSEDPETROLPRICES.scrollablePricesOnRightClick = function (e) {\r\n e.preventDefault();\r\n \r\n if ($(ns.Elements.ScrollRightLink).prop(ns.Constants.Disabled)) {\r\n return;\r\n }\r\n $(ns.Elements.ScrollRightLink).prop(ns.Constants.Disabled, true);\r\n\r\n var currentLeftMargin = $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft).replace(ns.Constants.Pixel, ''),\r\n scrollRightResultMarkerOffset = $(ns.Elements.ScrollEndMarkerResult).offset(),\r\n scrollRightBodyMarkerOffset = $(ns.Elements.ScrollRightBodyMarker).offset(),\r\n newLeftMargin = parseInt(currentLeftMargin) - ns.Constants.ResultWidth;\r\n\r\n if (scrollRightResultMarkerOffset.left > scrollRightBodyMarkerOffset.left) {\r\n $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft, newLeftMargin + ns.Constants.Pixel);\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbon(240);\r\n }\r\n else {\r\n $(ns.Elements.ScrollRightLink).fadeOut(300);\r\n }\r\n $(ns.Elements.ScrollLeftLink).fadeIn(300);\r\n\r\n setTimeout(function () {\r\n $(ns.Elements.ScrollRightLink).prop(ns.Constants.Disabled, false);\r\n }, 300);\r\n };\r\n\r\n // prices on left click\r\n CONFUSEDPETROLPRICES.scrollablePricesOnLeftClick = function (e) {\r\n e.preventDefault();\r\n\r\n if ($(ns.Elements.ScrollLeftLink).prop(ns.Constants.Disabled)) {\r\n return;\r\n }\r\n $(ns.Elements.ScrollLeftLink).prop(ns.Constants.Disabled, true);\r\n\r\n var currentLeftMargin = $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft).replace(ns.Constants.Pixel, ''),\r\n newLeftMargin = parseInt(currentLeftMargin) + ns.Constants.ResultWidth,\r\n marginBoundary = 0;\r\n\r\n if ($(window).width() > 583) {\r\n marginBoundary = ns.Constants.ResultWidth;\r\n if (newLeftMargin >= ns.Constants.ResultWidth) {\r\n $(ns.Elements.ScrollLeftLink).fadeOut(300);\r\n }\r\n }\r\n\r\n if (parseInt(currentLeftMargin) < marginBoundary) {\r\n if (newLeftMargin > ns.Constants.ResultWidth) {\r\n newLeftMargin = ns.Constants.ResultWidth;\r\n }\r\n $(ns.Elements.ResultsUl).css(ns.Constants.MarginLeft, newLeftMargin + ns.Constants.Pixel);\r\n $(ns.Elements.ScrollRightLink).fadeIn(300);\r\n }\r\n\r\n setTimeout(function () {\r\n $(ns.Elements.ScrollLeftLink).prop(ns.Constants.Disabled, false);\r\n }, 300);\r\n\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbonOnTimeout();\r\n };\r\n\r\n // handle cheapest ribbon on timeout\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbonOnTimeout = function () {\r\n setTimeout(function () {\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbon(0);\r\n }, 400);\r\n };\r\n\r\n // handle cheapest ribbon\r\n CONFUSEDPETROLPRICES.HandleCheapestRibbon = function (leftMargin) {\r\n\r\n // if: not desktop OR not sorted by distance OR static price has ribbon\r\n if ($(window).width() <= 583 ||\r\n $(ns.Elements.SortPricesByDistance).hasClass('results-filter--active') === false ||\r\n $($(ns.Elements.PetrolPriceResultsResult).first()[0]).find(ns.Elements.CheapestRibbon).length > 0) {\r\n\r\n // show ribbon\r\n $(ns.Elements.PetrolPriceResultsResult).each(function () {\r\n $(this).find(ns.Elements.CheapestRibbon).show();\r\n });\r\n\r\n } else {\r\n\r\n // hide ribbon (where scrollable price underlaps static price)\r\n $(ns.Elements.PetrolPriceResultsResult).each(function (index) {\r\n if ($(this).position().left <= leftMargin && index !== 0) {\r\n $(this).find(ns.Elements.CheapestRibbon).hide();\r\n } else {\r\n $(this).find(ns.Elements.CheapestRibbon).show();\r\n }\r\n });\r\n }\r\n };\r\n\r\n // opening hours link click\r\n CONFUSEDPETROLPRICES.openingHoursLinkClick = function () {\r\n\r\n // if mobile, place opening hours modal at correct scroll position\r\n if ($(window).width() <= 600) {\r\n var scrollLeft = $(ns.Elements.ResultsPanelBody).scrollLeft() + 40;\r\n $(ns.Elements.OpeningHoursModal).css(ns.Constants.Left, scrollLeft + ns.Constants.Pixel);\r\n }\r\n\r\n // ensure dimmer fills results panel\r\n var resultsPanelWidth = $(ns.Elements.PRFuelFinderResultsPanel).width();\r\n var resultsUlWidth = $(ns.Elements.ResultsUl).width() + ns.Constants.ResultWidth;\r\n if (resultsPanelWidth > resultsUlWidth) {\r\n $(ns.Elements.Dimmer).width(resultsPanelWidth);\r\n } else {\r\n $(ns.Elements.Dimmer).width('150%');\r\n }\r\n\r\n $(ns.Elements.OpeningHoursModal).fadeIn(300);\r\n $(ns.Elements.Dimmer).fadeIn(300);\r\n $(ns.Elements.OpeningHoursModal).addClass(ns.Classes.OpeningHoursLinkClicked);\r\n };\r\n\r\n // opening hours modal close click\r\n CONFUSEDPETROLPRICES.openingHoursModalCloseClick = function () {\r\n $(ns.Elements.OpeningHoursModal).fadeOut(300);\r\n $(ns.Elements.Dimmer).fadeOut(300);\r\n };\r\n\r\n // show results panel border\r\n CONFUSEDPETROLPRICES.showResultsPanelBorder = function () {\r\n $(ns.Elements.ResultsPanelBody).addClass(ns.Classes.ResultsPanelBodyBorder);\r\n };\r\n\r\n // hide results panel border\r\n CONFUSEDPETROLPRICES.hideResultsPanelBorder = function () {\r\n $(ns.Elements.ResultsPanelBody).removeClass(ns.Classes.ResultsPanelBodyBorder);\r\n };\r\n\r\n // initialise tooltips\r\n CONFUSEDPETROLPRICES.initTooltips = function () {\r\n\r\n $(ns.Elements.TooltipToggle).click(function (e) {\r\n if ($(this).hasClass(ns.Constants.Open)) {\r\n $(this).closest(ns.Elements.TooltipWrapper).find(ns.Elements.TooltipInfo).fadeOut();\r\n $(this).removeClass(ns.Constants.Open);\r\n }\r\n else {\r\n $(ns.Elements.TooltipToggle).removeClass(ns.Constants.Open);\r\n $(ns.Elements.TooltipInfo).fadeOut();\r\n $(this).closest(ns.Elements.TooltipWrapper).find(ns.Elements.TooltipInfo).fadeIn();\r\n $(this).addClass(ns.Constants.Open);\r\n }\r\n e.preventDefault();\r\n });\r\n\r\n $(ns.Elements.TooltipInfoDismiss).click(function(e) {\r\n $(this).closest(ns.Elements.TooltipInfo).fadeOut();\r\n $(ns.Elements.TooltipToggle).removeClass(ns.Constants.Open);\r\n e.preventDefault();\r\n });\r\n };\r\n\r\n // initialise opening hours\r\n CONFUSEDPETROLPRICES.initOpeningHours = function () {\r\n\r\n // on price list click\r\n $(ns.Elements.ResultsUl).click(function () {\r\n var openingHoursLinkClicked = $(ns.Elements.OpeningHoursModal).hasClass(ns.Classes.OpeningHoursLinkClicked);\r\n\r\n // if dimmer visible (and not due to opening hours link being clicked)\r\n if ($(ns.Elements.Dimmer).is(ns.Constants.Visible) &&\r\n openingHoursLinkClicked === false) {\r\n\r\n // close opening hours modal\r\n CONFUSEDPETROLPRICES.openingHoursModalCloseClick();\r\n\r\n // otherwise remove opening hours link clicked\r\n } else if (openingHoursLinkClicked) {\r\n $(ns.Elements.OpeningHoursModal).removeClass(ns.Classes.OpeningHoursLinkClicked);\r\n }\r\n });\r\n };\r\n\r\n // show search form postcode section\r\n CONFUSEDPETROLPRICES.showSearchFormPostcodeSection = function () {\r\n $(ns.Elements.SFLandingPanelMainPostcode).fadeIn();\r\n };\r\n\r\n // initialise internet explorer\r\n CONFUSEDPETROLPRICES.initInternetExplorer = function () {\r\n\r\n // ensure internet explorer\r\n if (!CONFUSEDPETROLPRICES.isInternetExplorer()) {\r\n return;\r\n }\r\n\r\n // handle search form postcode and get prices width\r\n $(ns.Elements.SFPostcodeWrapper).css(ns.Constants.MaxWidth, 300);\r\n $(ns.Elements.SFGetPrices).css(ns.Constants.MaxWidth, 250);\r\n\r\n // handle results form current location positioning\r\n $(ns.Elements.RSCurrentLocationTooltipWrapper).css(ns.Constants.MarginLeft, -250);\r\n $(ns.Elements.RSCurrentLocationTooltipWrapper).css(ns.Constants.MarginTop, 50);\r\n $(ns.Elements.RSPostcodeError).css(ns.Constants.MarginBottom, -40);\r\n };\r\n\r\n // initialise safari on mac\r\n CONFUSEDPETROLPRICES.initSafariOnMac = function () {\r\n\r\n // ensure safari on mac\r\n if (!CONFUSEDPETROLPRICES.isSafariOnMac()) {\r\n return;\r\n }\r\n\r\n // handle search form postcode and get prices width\r\n $(ns.Elements.SFLandingPanelMainPostcode).css(ns.Constants.MarginLeft, '28%');\r\n $(ns.Elements.SFLandingPanelMainPostcode).css(ns.Constants.MarginRight, '28%');\r\n\r\n // handle prices search fuel type and radius\r\n $(ns.Elements.RSFuelType).css(ns.Constants.Border, 1);\r\n $(ns.Elements.RSFuelType).css(ns.Constants.MarginTop, 10);\r\n $(ns.Elements.RSRadius).css(ns.Constants.Border, 1);\r\n $(ns.Elements.RSRadius).css(ns.Constants.MarginTop, 10);\r\n };\r\n\r\n // check if internet explorer\r\n CONFUSEDPETROLPRICES.isInternetExplorer = function () {\r\n var ua = window.navigator.userAgent;\r\n var isMsIe = ua.indexOf(ns.Constants.MsIe) !== -1;\r\n var isMsIe11 = ua.indexOf(ns.Constants.MsIe11) !== -1;\r\n\r\n if (!isMsIe && !isMsIe11) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // check if safari on mac\r\n CONFUSEDPETROLPRICES.isSafariOnMac = function () {\r\n var ua = window.navigator.userAgent;\r\n var isMacintosh = ua.indexOf(ns.Constants.Macintosh) !== -1;\r\n var isSafari = ((ua.indexOf(ns.Constants.Safari) !== -1) && (ua.indexOf(ns.Constants.Chrome) === -1));\r\n var isIPad = ua.indexOf(ns.Constants.IPad) !== -1;\r\n var isIPod = ua.indexOf(ns.Constants.IPod) !== -1;\r\n var isIPhone = ua.indexOf(ns.Constants.IPhone) !== -1;\r\n\r\n if ((!isMacintosh && !isSafari) || (isIPad || isIPod || isIPhone)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n}(CONFUSEDPETROLPRICES.UiElements, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDPETROLPRICES = CONFUSEDPETROLPRICES || {};\r\nCONFUSEDPETROLPRICES.SearchFormValidation = CONFUSEDPETROLPRICES.SearchFormValidation || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n // html elements\r\n ns.Elements = {\r\n SFFuelType: 'input[name=\\'sfFuelType\\']',\r\n SFFuelTypeSelected: 'input[name=\\'sfFuelType\\']:checked',\r\n SFFuelTypeError: '#sfFuelTypeError',\r\n SFRadiusError: '#sfRadiusError',\r\n SFPostcode: '#sfPostcode',\r\n SFPostcodeErrorEnabled: '#sfPostcodeErrorEnabled',\r\n SFPostcodeError: '#sfPostcodeError',\r\n RSFuelType: '#rsFuelType',\r\n RSFuelTypeSelected: '#rsFuelType option:selected',\r\n RSFuelTypeError: '#rsFuelTypeError',\r\n RSRadius: '#rsRadius',\r\n RSRadiusSelected: '#rsRadius option:selected',\r\n RSRadiusError: '#rsRadiusError',\r\n RSPostcode: '#rsPostcode',\r\n RSPostcodeErrorEnabled: '#rsPostcodeErrorEnabled',\r\n RSPostcodeError: '#rsPostcodeError'\r\n };\r\n\r\n // validation constants\r\n ns.ValidationConstants = {\r\n FuelTypes: [1, 2, 4, 5, 6, 7],\r\n Radius: [5, 10, 25],\r\n PostcodeRegex: '^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})$'\r\n };\r\n\r\n // error message constants\r\n ns.ErrorMessageConstants = {\r\n FuelType: 'Please select a fuel type',\r\n Radius: 'Please enter a valid radius',\r\n Postcode: 'Please enter a valid postcode'\r\n };\r\n\r\n // validation methods\r\n ns.Validation = {\r\n FuelType: function (fuelType) {\r\n var parsedFuelType = parseInt(fuelType, 10);\r\n if (isNaN(parsedFuelType)) {\r\n return false;\r\n }\r\n return (jQuery.inArray(parsedFuelType, ns.ValidationConstants.FuelTypes) !== -1);\r\n },\r\n Radius: function (radius) {\r\n var parsedRadius = parseInt(radius, 10);\r\n if (isNaN(parsedRadius)) {\r\n return false;\r\n }\r\n return (jQuery.inArray(parsedRadius, ns.ValidationConstants.Radius) !== -1);\r\n },\r\n Postcode: function (postcode) {\r\n var re = new RegExp(ns.ValidationConstants.PostcodeRegex);\r\n return re.test(postcode);\r\n },\r\n MyLocation: function (postcodeLatitude, postcodeLongitude) {\r\n return postcodeLatitude !== 0 && postcodeLongitude !== 0;\r\n }\r\n };\r\n\r\n // bind validation\r\n CONFUSEDPETROLPRICES.bindValidation = function () {\r\n\r\n // search form: fuel type\r\n $(ns.Elements.SFFuelType).change(function () {\r\n CONFUSEDPETROLPRICES.validateSFFuelType($(ns.Elements.SFFuelTypeSelected).val());\r\n });\r\n\r\n // search form: postcode\r\n $(ns.Elements.SFPostcode).keyup(function () {\r\n if ($(ns.Elements.SFPostcodeErrorEnabled).is(':checked')) {\r\n CONFUSEDPETROLPRICES.validateSFPostcode($(ns.Elements.SFPostcode).val());\r\n }\r\n });\r\n\r\n $(ns.Elements.SFPostcode).blur(function () {\r\n CONFUSEDPETROLPRICES.enablePostcodeError();\r\n CONFUSEDPETROLPRICES.validateSFPostcode($(ns.Elements.SFPostcode).val());\r\n });\r\n\r\n // radius search: fuel type\r\n $(ns.Elements.RSFuelType).change(function () {\r\n CONFUSEDPETROLPRICES.validateRSFuelType($(ns.Elements.RSFuelTypeSelected).val());\r\n });\r\n\r\n // radius search: radius\r\n $(ns.Elements.RSRadius).change(function () {\r\n CONFUSEDPETROLPRICES.validateRSRadius($(ns.Elements.RSRadiusSelected).val());\r\n });\r\n\r\n // radius search: postcode\r\n $(ns.Elements.RSPostcode).keyup(function () {\r\n if ($(ns.Elements.RSPostcodeErrorEnabled).is(':checked')) {\r\n CONFUSEDPETROLPRICES.validateRSPostcode($(ns.Elements.RSPostcode).val());\r\n }\r\n });\r\n\r\n $(ns.Elements.RSPostcode).blur(function () {\r\n CONFUSEDPETROLPRICES.enablePostcodeError();\r\n CONFUSEDPETROLPRICES.validateRSPostcode($(ns.Elements.RSPostcode).val());\r\n });\r\n };\r\n\r\n // validate search form\r\n CONFUSEDPETROLPRICES.validateSearchForm = function (fuelType, radius, postcode, postcodeLatitude, postcodeLongitude) {\r\n var validFuelType = CONFUSEDPETROLPRICES.validateSFFuelType(fuelType);\r\n var validRadius = CONFUSEDPETROLPRICES.validateSFRadius(radius);\r\n\r\n var validPostcode;\r\n if (postcode !== CONFUSEDPETROLPRICES.Constants.MyLocation) {\r\n validPostcode = CONFUSEDPETROLPRICES.validateSFPostcode(postcode);\r\n } else {\r\n validPostcode = CONFUSEDPETROLPRICES.validateSFMyLocation(postcodeLatitude, postcodeLongitude);\r\n }\r\n\r\n return (validFuelType && validRadius && validPostcode);\r\n };\r\n\r\n // validate search form: fuel type\r\n CONFUSEDPETROLPRICES.validateSFFuelType = function (fuelType) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.FuelType(fuelType),\r\n $(ns.Elements.SFFuelTypeError),\r\n ns.ErrorMessageConstants.FuelType\r\n );\r\n };\r\n\r\n // validate search form: radius\r\n CONFUSEDPETROLPRICES.validateSFRadius = function (radius) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.Radius(radius),\r\n $(ns.Elements.SFRadiusError),\r\n ns.ErrorMessageConstants.Radius\r\n );\r\n };\r\n\r\n // validate search form: postcode\r\n CONFUSEDPETROLPRICES.validateSFPostcode = function (postcode) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.Postcode(postcode),\r\n $(ns.Elements.SFPostcodeError),\r\n ns.ErrorMessageConstants.Postcode\r\n );\r\n };\r\n\r\n // validate search form: my location\r\n CONFUSEDPETROLPRICES.validateSFMyLocation = function (postcodeLatitude, postcodeLongitude) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.MyLocation(postcodeLatitude, postcodeLongitude),\r\n $(ns.Elements.SFPostcodeError),\r\n ns.ErrorMessageConstants.Postcode\r\n );\r\n };\r\n\r\n // validate radius search\r\n CONFUSEDPETROLPRICES.validateRadiusSearch = function (fuelType, radius, postcode, postcodeLatitude, postcodeLongitude) {\r\n var validFuelType = CONFUSEDPETROLPRICES.validateRSFuelType(fuelType);\r\n var validRadius = CONFUSEDPETROLPRICES.validateRSRadius(radius);\r\n\r\n var validPostcode;\r\n if (postcode !== CONFUSEDPETROLPRICES.Constants.MyLocation) {\r\n validPostcode = CONFUSEDPETROLPRICES.validateRSPostcode(postcode);\r\n } else {\r\n validPostcode = CONFUSEDPETROLPRICES.validateRSMyLocation(postcodeLatitude, postcodeLongitude);\r\n }\r\n\r\n return (validFuelType && validRadius && validPostcode);\r\n };\r\n\r\n // validate radius search: fuel type\r\n CONFUSEDPETROLPRICES.validateRSFuelType = function (fuelType) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.FuelType(fuelType),\r\n $(ns.Elements.RSFuelTypeError),\r\n ns.ErrorMessageConstants.FuelType\r\n );\r\n };\r\n\r\n // validate radius search: radius\r\n CONFUSEDPETROLPRICES.validateRSRadius = function (radius) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.Radius(radius),\r\n $(ns.Elements.RSRadiusError),\r\n ns.ErrorMessageConstants.Radius\r\n );\r\n };\r\n\r\n // validate radius search: postcode\r\n CONFUSEDPETROLPRICES.validateRSPostcode = function (postcode) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.Postcode(postcode),\r\n $(ns.Elements.RSPostcodeError),\r\n ns.ErrorMessageConstants.Postcode\r\n );\r\n };\r\n\r\n // validate radius search: my location\r\n CONFUSEDPETROLPRICES.validateRSMyLocation = function (postcodeLatitude, postcodeLongitude) {\r\n return CONFUSEDPETROLPRICES.handleElementValidation(\r\n ns.Validation.MyLocation(postcodeLatitude, postcodeLongitude),\r\n $(ns.Elements.RSPostcodeError),\r\n ns.ErrorMessageConstants.Postcode\r\n );\r\n };\r\n\r\n // handle element validation\r\n CONFUSEDPETROLPRICES.handleElementValidation = function (isValid, element, errorMessage) {\r\n if (isValid) {\r\n element.html('');\r\n element.hide();\r\n return true;\r\n }\r\n\r\n element.html(errorMessage);\r\n element.show();\r\n return false;\r\n };\r\n\r\n // enable postcode error\r\n CONFUSEDPETROLPRICES.enablePostcodeError = function () {\r\n $(ns.Elements.SFPostcodeErrorEnabled).prop('checked', true);\r\n $(ns.Elements.RSPostcodeErrorEnabled).prop('checked', true);\r\n };\r\n\r\n // disbale postcode error\r\n CONFUSEDPETROLPRICES.disablePostcodeError = function () {\r\n $(ns.Elements.SFPostcodeErrorEnabled).prop('checked', false);\r\n $(ns.Elements.RSPostcodeErrorEnabled).prop('checked', false);\r\n };\r\n\r\n}(CONFUSEDPETROLPRICES.SearchFormValidation, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {};\r\nCONFUSEDCMS.ProductHeroCTA = CONFUSEDCMS.ProductHeroCTA || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n ns.Constants = {\r\n CAR: 0,\r\n VAN: 1,\r\n BIKE: 2\r\n };\r\n\r\n\r\n ns.Vehicle = function () {\r\n var self = this;\r\n self.RegNumber = ko.observable('');\r\n self.VehicleType = ko.observable('');\r\n };\r\n\r\n ns.BaseUrl = function () {\r\n return $('.js-get-a-quote-btn').attr('href');\r\n };\r\n\r\n ns.RegNumberLookup = function () {\r\n var self = this;\r\n self.Vehicle = new ns.Vehicle();\r\n self.VehicleNotFound = ko.observable(false);\r\n self.VanFound = ko.observable(false);\r\n self.BikeFound = ko.observable(false);\r\n\r\n self.ShowModalDimmer = ko.computed(function () {\r\n if (self.VehicleNotFound() || self.VanFound() || self.BikeFound()) {\r\n $('.modal-dimmer').show();\r\n return true;\r\n }\r\n $('.modal-dimmer').hide();\r\n return false;\r\n });\r\n\r\n self.InitialiseModule = function () {\r\n ko.applyBindings(self);\r\n };\r\n\r\n self.Reset = function () {\r\n self.VanFound(false);\r\n self.BikeFound(false);\r\n self.VehicleNotFound(false);\r\n };\r\n\r\n self.EditReg = function () {\r\n self.Reset();\r\n $('.js-get-a-quote-input').focus();\r\n $('.js-get-a-quote-input').select();\r\n };\r\n\r\n self.Lookup = function () {\r\n var regNumber = $('.js-get-a-quote-input').val();\r\n var baseUrl = ns.BaseUrl();\r\n if (regNumber === '') {\r\n window.location.href = baseUrl;\r\n return;\r\n }\r\n self.Vehicle.VehicleType(ns.Constants.CAR);\r\n self.Vehicle.RegNumber(regNumber);\r\n var carRegQuoteUrl = $('.js-get-a-quote-input').attr('data-quote-entry-url');\r\n \r\n\r\n $.ajax({\r\n url: '/api/lookupv2/vehiclelookup',\r\n contentType: 'text/json',\r\n type: 'POST',\r\n data: ko.toJSON({\r\n RegistrationNumber: self.Vehicle.RegNumber()\r\n }),\r\n success: function (data) {\r\n switch (data) {\r\n case ns.Constants.CAR:\r\n window.location.href = baseUrl + carRegQuoteUrl + self.Vehicle.RegNumber();\r\n return;\r\n case ns.Constants.VAN:\r\n self.VanFound(true);\r\n break;\r\n case ns.Constants.BIKE:\r\n self.BikeFound(true);\r\n break;\r\n default:\r\n self.VehicleNotFound(true);\r\n }\r\n\r\n\r\n },\r\n error: function () {\r\n self.VehicleNotFound(true);\r\n }\r\n });\r\n };\r\n };\r\n\r\n ns.PostcodeLookup = function() {\r\n var self = this;\r\n\r\n self.InitialiseModule = function () {\r\n ko.applyBindings(self);\r\n };\r\n\r\n self.CheckPostcode = function (regValue) {\r\n regValue = $.trim(regValue);\r\n var regPostcode =\r\n new RegExp(\r\n '^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})$');\r\n if (regPostcode.test(regValue)) {\r\n return true;\r\n } else {\r\n if ($('.input-with-button + .error-message').length < 1) {\r\n var $errorMsg = $('', { text: 'Please enter a valid postcode', 'class': 'error-message' });\r\n $errorMsg.insertAfter('.input-with-button');\r\n }\r\n return false;\r\n }\r\n };\r\n\r\n self.Lookup = function () {\r\n var postCode = $('.js-get-a-quote-input').val();\r\n var baseUrl = ns.BaseUrl();\r\n if (postCode === '') {\r\n window.location.href = baseUrl;\r\n return;\r\n }\r\n \r\n var postCodeQuoteUrl = $('.js-get-a-quote-input').attr('data-quote-entry-url');\r\n\r\n if (self.CheckPostcode(postCode)) {\r\n window.location.href = baseUrl + postCodeQuoteUrl + postCode;\r\n }\r\n\r\n \r\n };\r\n };\r\n\r\n CONFUSEDCMS.setupProductCtas = function() {\r\n if ($('input.js-get-a-quote-input[data-quote-product-id=\"2\"]').length > 0) {\r\n\r\n var motorHeroCta = new CONFUSEDCMS.ProductHeroCTA.RegNumberLookup();\r\n motorHeroCta.InitialiseModule();\r\n\r\n $('input.js-get-a-quote-input').on('keydown',\r\n function (e) {\r\n if (e.keyCode === 13) {\r\n e.preventDefault();\r\n motorHeroCta.Lookup();\r\n }\r\n });\r\n }\r\n\r\n if ($('input.js-get-a-quote-input[data-quote-product-id=\"5\"]').length > 0) {\r\n\r\n var homeHeroCta = new CONFUSEDCMS.ProductHeroCTA.PostcodeLookup();\r\n homeHeroCta.InitialiseModule();\r\n\r\n $('input.js-get-a-quote-input').on('keydown',\r\n function (e) {\r\n if (e.keyCode === 13) {\r\n e.preventDefault();\r\n homeHeroCta.Lookup();\r\n }\r\n });\r\n } \r\n };\r\n\r\n}(CONFUSEDCMS.ProductHeroCTA, jQuery));\r\n","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDCARFINANCECALCULATORAPP = CONFUSEDCARFINANCECALCULATORAPP || {},\r\n Confused = Confused || {},\r\n newrelic = newrelic || {};\r\n\r\n(function(ns, newrelic, $) {\r\n 'use strict';\r\n\r\n // html elements\r\n ns.Elements = {\r\n ProviderLowRepresentativeExample: '#hdnProviderLowRepresentativeExample',\r\n ProviderLowTier1000To1999Percentage: '#hdnProviderLowTier1000To1999Percentage',\r\n ProviderLowTier2000To2999Percentage: '#hdnProviderLowTier2000To2999Percentage',\r\n ProviderLowTier3000To4999Percentage: '#hdnProviderLowTier3000To4999Percentage',\r\n ProviderLowTier5000To7499Percentage: '#hdnProviderLowTier5000To7499Percentage',\r\n ProviderLowTier7500To19999Percentage: '#hdnProviderLowTier7500To19999Percentage',\r\n ProviderLowTier20000To36000Percentage: '#hdnProviderLowTier20000To36000Percentage',\r\n ProviderModerateRepresentativeExample: '#hdnProviderModerateRepresentativeExample',\r\n ProviderModerateTier1000To1999Percentage: '#hdnProviderModerateTier1000To1999Percentage',\r\n ProviderModerateTier2000To2999Percentage: '#hdnProviderModerateTier2000To2999Percentage',\r\n ProviderModerateTier3000To4999Percentage: '#hdnProviderModerateTier3000To4999Percentage',\r\n ProviderModerateTier5000To7499Percentage: '#hdnProviderModerateTier5000To7499Percentage',\r\n ProviderModerateTier7500To19999Percentage: '#hdnProviderModerateTier7500To19999Percentage',\r\n ProviderModerateTier20000To36000Percentage: '#hdnProviderModerateTier20000To36000Percentage',\r\n ProviderHighRepresentativeExample: '#hdnProviderHighRepresentativeExample',\r\n ProviderHighTier1000To1999Percentage: '#hdnProviderHighTier1000To1999Percentage',\r\n ProviderHighTier2000To2999Percentage: '#hdnProviderHighTier2000To2999Percentage',\r\n ProviderHighTier3000To4999Percentage: '#hdnProviderHighTier3000To4999Percentage',\r\n ProviderHighTier5000To7499Percentage: '#hdnProviderHighTier5000To7499Percentage',\r\n ProviderHighTier7500To19999Percentage: '#hdnProviderHighTier7500To19999Percentage',\r\n ProviderHighTier20000To36000Percentage: '#hdnProviderHighTier20000To36000Percentage',\r\n CarFinanceCalculatorWidget: '#CarFinanceCalculatorWidget',\r\n CarFinanceCalculatorStartApplication: '#CarFinanceCalculatorStartApplication',\r\n CarFinanceCalculatorSpinner: '#CarFinanceCalculatorSpinner',\r\n CarFinanceCalculatorGetQuote: '#CarFinanceCalculatorGetQuote',\r\n CalculateButton: '#btnCalculate',\r\n RecalculateText: '#hdnRecalculateText',\r\n CalculateErrorHowMuch: '#CalculateErrorHowMuch',\r\n CalculateErrorHowLong: '#CalculateErrorHowLong',\r\n ProviderLowSection: '#ProviderLowSection',\r\n ProviderModerateSection: '#ProviderModerateSection',\r\n ProviderHighSection: '#ProviderHighSection',\r\n StartApplicationButton: '#btnStartApplication',\r\n GetAQuoteButton: '#btnGetAQuote',\r\n CalculationError: '#CalculationError',\r\n ProviderLowTitle: '#ProviderLowTitle',\r\n ProviderModerateTitle: '#ProviderModerateTitle',\r\n ProviderHighTitle: '#ProviderHighTitle',\r\n ProviderTitleOnMobile: '#ProviderTitleOnMobile'\r\n };\r\n\r\n // constants\r\n ns.Constants = {\r\n CarFinanceCalculatorWidgetId: 'CarFinanceCalculatorWidget',\r\n CalculateErrorMessageHowMuch: 'Please select how much you want to borrow',\r\n CalculateErrorMessageHowLong: 'Please select over how long',\r\n CarFinanceCalculatorSpinnerTimeout: 1000,\r\n CarFinanceCalculatorAppName: 'CarFinanceCalculator',\r\n AprExampleTableTabActive: 'apr-example-table__tab--active',\r\n ProviderLowTitleOnMobile: 'ProviderLowTitleOnMobile',\r\n ProviderModerateTitleOnMobile: 'ProviderModerateTitleOnMobile',\r\n ProviderHighTitleOnMobile: 'ProviderHighTitleOnMobile',\r\n ProviderLow: 'ProviderLow',\r\n ProviderModerate: 'ProviderModerate',\r\n ProviderHigh: 'ProviderHigh'\r\n };\r\n\r\n // tokens\r\n ns.Tokens = {\r\n HowMuch: '[HOWMUCH]',\r\n HowLong: '[HOWLONG]'\r\n };\r\n\r\n // utils functions\r\n ns.Utils = {\r\n\r\n // bind provider low\r\n BindProviderLow: function (provider) {\r\n provider.RepresentativeExample($(ns.Elements.ProviderLowRepresentativeExample).val());\r\n provider.Tier1000To1999Percentage($(ns.Elements.ProviderLowTier1000To1999Percentage).val());\r\n provider.Tier2000To2999Percentage($(ns.Elements.ProviderLowTier2000To2999Percentage).val());\r\n provider.Tier3000To4999Percentage($(ns.Elements.ProviderLowTier3000To4999Percentage).val());\r\n provider.Tier5000To7499Percentage($(ns.Elements.ProviderLowTier5000To7499Percentage).val());\r\n provider.Tier7500To19999Percentage($(ns.Elements.ProviderLowTier7500To19999Percentage).val());\r\n provider.Tier20000To36000Percentage($(ns.Elements.ProviderLowTier20000To36000Percentage).val());\r\n },\r\n\r\n // bind provider moderate\r\n BindProviderModerate: function (provider) {\r\n provider.RepresentativeExample($(ns.Elements.ProviderModerateRepresentativeExample).val());\r\n provider.Tier1000To1999Percentage($(ns.Elements.ProviderModerateTier1000To1999Percentage).val());\r\n provider.Tier2000To2999Percentage($(ns.Elements.ProviderModerateTier2000To2999Percentage).val());\r\n provider.Tier3000To4999Percentage($(ns.Elements.ProviderModerateTier3000To4999Percentage).val());\r\n provider.Tier5000To7499Percentage($(ns.Elements.ProviderModerateTier5000To7499Percentage).val());\r\n provider.Tier7500To19999Percentage($(ns.Elements.ProviderModerateTier7500To19999Percentage).val());\r\n provider.Tier20000To36000Percentage($(ns.Elements.ProviderModerateTier20000To36000Percentage).val());\r\n },\r\n\r\n // bind provider high\r\n BindProviderHigh: function (provider) {\r\n provider.RepresentativeExample($(ns.Elements.ProviderHighRepresentativeExample).val());\r\n provider.Tier1000To1999Percentage($(ns.Elements.ProviderHighTier1000To1999Percentage).val());\r\n provider.Tier2000To2999Percentage($(ns.Elements.ProviderHighTier2000To2999Percentage).val());\r\n provider.Tier3000To4999Percentage($(ns.Elements.ProviderHighTier3000To4999Percentage).val());\r\n provider.Tier5000To7499Percentage($(ns.Elements.ProviderHighTier5000To7499Percentage).val());\r\n provider.Tier7500To19999Percentage($(ns.Elements.ProviderHighTier7500To19999Percentage).val());\r\n provider.Tier20000To36000Percentage($(ns.Elements.ProviderHighTier20000To36000Percentage).val());\r\n },\r\n\r\n // new relic event\r\n WriteNewRelicPageEvent: function (eventName, eventArgs) {\r\n eventArgs = eventArgs || {};\r\n eventArgs = ns.Utils.GetCustomerFromCookies(eventArgs);\r\n if (newrelic && newrelic.addPageAction !== undefined) {\r\n newrelic.addPageAction(CONFUSEDCARFINANCECALCULATORAPP.Constants.CarFinanceCalculatorAppName + eventName, eventArgs);\r\n }\r\n },\r\n\r\n // get customer from cookies\r\n GetCustomerFromCookies: function (object) {\r\n object = object || {};\r\n var cookies = document.cookie.split(';'),\r\n xUniqueCustomerSessionIdString = 'X-UniqueCustomerSessionID',\r\n xUniqueCustomerCookieIdString = 'X-UniqueCustomerCookieID',\r\n xUniqueCustomerSessionId = '',\r\n xUniqueCustomerCookieId = '';\r\n\r\n for (var c = 0; c < cookies.length; c++) {\r\n if (cookies[c].indexOf(xUniqueCustomerSessionIdString) !== -1) {\r\n xUniqueCustomerSessionId = cookies[c].split('=')[1];\r\n }\r\n if (cookies[c].indexOf(xUniqueCustomerCookieIdString) !== -1) {\r\n xUniqueCustomerCookieId = cookies[c].split('=')[1];\r\n }\r\n }\r\n object.XUniqueCustomerSessionIDString = xUniqueCustomerSessionId;\r\n object.XUniqueCustomerCookieIDString = xUniqueCustomerCookieId;\r\n return object;\r\n },\r\n\r\n // show provider low section\r\n ShowProviderLowSection: function () {\r\n $(ns.Elements.ProviderLowSection).show();\r\n $(ns.Elements.ProviderModerateSection).hide();\r\n $(ns.Elements.ProviderHighSection).hide();\r\n\r\n $(ns.Elements.ProviderLowTitle).addClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderModerateTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderHighTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n },\r\n\r\n // show provider moderate section\r\n ShowProviderModerateSection: function () {\r\n $(ns.Elements.ProviderLowSection).hide();\r\n $(ns.Elements.ProviderModerateSection).show();\r\n $(ns.Elements.ProviderHighSection).hide();\r\n\r\n $(ns.Elements.ProviderLowTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderModerateTitle).addClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderHighTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n },\r\n\r\n // show provider high section\r\n ShowProviderHighSection: function () {\r\n $(ns.Elements.ProviderLowSection).hide();\r\n $(ns.Elements.ProviderModerateSection).hide();\r\n $(ns.Elements.ProviderHighSection).show();\r\n\r\n $(ns.Elements.ProviderLowTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderModerateTitle).removeClass(ns.Constants.AprExampleTableTabActive);\r\n $(ns.Elements.ProviderHighTitle).addClass(ns.Constants.AprExampleTableTabActive);\r\n },\r\n\r\n // number with commas\r\n NumberWithCommas: function (num) {\r\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\r\n },\r\n\r\n // number with decimal place\r\n NumberWithDecimalPlace: function (num) {\r\n num = parseFloat(num);\r\n\r\n if (num.toString().indexOf('.') === -1) {\r\n num = num.toFixed(1);\r\n }\r\n\r\n return num;\r\n }\r\n };\r\n\r\n // blank provider\r\n ns.Provider = function () {\r\n var self = this;\r\n self.RepresentativeExample = ko.observable('');\r\n self.Tier1000To1999Percentage = ko.observable(0.0);\r\n self.Tier2000To2999Percentage = ko.observable(0.0);\r\n self.Tier3000To4999Percentage = ko.observable(0.0);\r\n self.Tier5000To7499Percentage = ko.observable(0.0);\r\n self.Tier7500To19999Percentage = ko.observable(0.0);\r\n self.Tier20000To36000Percentage = ko.observable(0.0);\r\n self.CalculationTierPercentage = ko.observable(0.0);\r\n self.CalculationMonthlyRepayment = ko.observable(0.0);\r\n self.CalculationTotalRepayment = ko.observable(0.0);\r\n self.TokenizedRepresentativeExample = ko.observable('');\r\n };\r\n\r\n // car finance calculator form\r\n ns.CarFinanceCalculatorForm = function () {\r\n var self = this;\r\n self.ProviderLow = new ns.Provider();\r\n self.ProviderModerate = new ns.Provider();\r\n self.ProviderHigh = new ns.Provider();\r\n self.HowMuch = ko.observable('');\r\n self.HowLong = ko.observable('');\r\n\r\n // initialise form\r\n self.Initialise = function () {\r\n \r\n // bind to knockout\r\n ko.applyBindings(self, document.getElementById(ns.Constants.CarFinanceCalculatorWidgetId));\r\n\r\n // bind providers\r\n ns.Utils.BindProviderLow(self.ProviderLow);\r\n ns.Utils.BindProviderModerate(self.ProviderModerate);\r\n ns.Utils.BindProviderHigh(self.ProviderHigh);\r\n };\r\n\r\n // on How Much\r\n self.onHowMuch = function () {\r\n self.ValidateHowMuch();\r\n };\r\n\r\n // on How Long\r\n self.onHowLong = function () {\r\n self.ValidateHowLong();\r\n };\r\n\r\n // calculate\r\n self.Calculate = function () {\r\n\r\n // validation\r\n var isHowMuchValid = self.ValidateHowMuch();\r\n var isHowLongValid = self.ValidateHowLong();\r\n if (!isHowMuchValid || !isHowLongValid) {\r\n return;\r\n }\r\n\r\n // show spinner\r\n $(ns.Elements.CarFinanceCalculatorStartApplication).hide();\r\n $(ns.Elements.CarFinanceCalculatorGetQuote).hide();\r\n $(ns.Elements.CalculationError).hide();\r\n $(ns.Elements.CarFinanceCalculatorSpinner).show();\r\n\r\n setTimeout(function () {\r\n\r\n // do calculation\r\n if (!self.DoCalculation()) {\r\n CONFUSEDCARFINANCECALCULATORAPP.Utils.WriteNewRelicPageEvent('CalculationFailed');\r\n\r\n $(ns.Elements.CarFinanceCalculatorSpinner).hide();\r\n $(ns.Elements.CalculationError).show();\r\n return;\r\n }\r\n\r\n // show 'get a quote'\r\n $(ns.Elements.CalculateButton).html($(ns.Elements.RecalculateText).val());\r\n ns.Utils.ShowProviderLowSection();\r\n $(ns.Elements.CarFinanceCalculatorSpinner).hide();\r\n $(ns.Elements.CarFinanceCalculatorGetQuote).show();\r\n\r\n // scroll to calculator\r\n $('body').animate({ scrollTop: $(ns.Elements.CarFinanceCalculatorWidget).offset().top });\r\n\r\n }, ns.Constants.CarFinanceCalculatorSpinnerTimeout);\r\n\r\n };\r\n\r\n // validate how much\r\n self.ValidateHowMuch = function () {\r\n if (!self.HowMuch()) {\r\n $(ns.Elements.CalculateErrorHowMuch).text(ns.Constants.CalculateErrorMessageHowMuch);\r\n return false;\r\n }\r\n\r\n $(ns.Elements.CalculateErrorHowMuch).text('');\r\n return true;\r\n };\r\n\r\n // validate how long\r\n self.ValidateHowLong = function () {\r\n if (!self.HowLong()) {\r\n $(ns.Elements.CalculateErrorHowLong).text(ns.Constants.CalculateErrorMessageHowLong);\r\n return false;\r\n }\r\n\r\n $(ns.Elements.CalculateErrorHowLong).text('');\r\n return true;\r\n };\r\n\r\n // do calculation\r\n self.DoCalculation = function () {\r\n\r\n // validate calculation data\r\n if (!CONFUSEDCARFINANCECALCULATORAPP.Helper.validateCalculationData(self.HowMuch(), self.HowLong(),\r\n self.ProviderLow, self.ProviderModerate, self.ProviderHigh)) {\r\n return false;\r\n }\r\n\r\n // obtain tier percentage for providers\r\n self.ProviderLow.CalculationTierPercentage(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTierPercentage(\r\n self.HowMuch(),\r\n self.ProviderLow\r\n ));\r\n\r\n self.ProviderModerate.CalculationTierPercentage(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTierPercentage(\r\n self.HowMuch(),\r\n self.ProviderModerate\r\n ));\r\n\r\n self.ProviderHigh.CalculationTierPercentage(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTierPercentage(\r\n self.HowMuch(),\r\n self.ProviderHigh\r\n ));\r\n\r\n // validate tier percentage for providers\r\n if (self.ProviderLow.CalculationTierPercentage() === null ||\r\n self.ProviderModerate.CalculationTierPercentage() === null ||\r\n self.ProviderHigh.CalculationTierPercentage() === null) {\r\n return false;\r\n }\r\n\r\n // obtain monthly repayment for providers\r\n self.ProviderLow.CalculationMonthlyRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainMonthlyRepayment(\r\n self.ProviderLow.CalculationTierPercentage(),\r\n self.HowMuch(),\r\n self.HowLong()\r\n ));\r\n\r\n self.ProviderModerate.CalculationMonthlyRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainMonthlyRepayment(\r\n self.ProviderModerate.CalculationTierPercentage(),\r\n self.HowMuch(),\r\n self.HowLong()\r\n ));\r\n\r\n self.ProviderHigh.CalculationMonthlyRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainMonthlyRepayment(\r\n self.ProviderHigh.CalculationTierPercentage(),\r\n self.HowMuch(),\r\n self.HowLong()\r\n ));\r\n\r\n // obtain total repayment for providers\r\n self.ProviderLow.CalculationTotalRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTotalRepayment(\r\n self.ProviderLow.CalculationMonthlyRepayment(),\r\n self.HowLong()\r\n ));\r\n\r\n self.ProviderModerate.CalculationTotalRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTotalRepayment(\r\n self.ProviderModerate.CalculationMonthlyRepayment(),\r\n self.HowLong()\r\n ));\r\n\r\n self.ProviderHigh.CalculationTotalRepayment(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTotalRepayment(\r\n self.ProviderHigh.CalculationMonthlyRepayment(),\r\n self.HowLong()\r\n ));\r\n\r\n // obtain tokenized representative example\r\n self.ProviderLow.TokenizedRepresentativeExample(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTokenizedRepresentativeExample(\r\n self.ProviderLow.CalculationTierPercentage(),\r\n self.ProviderLow.CalculationMonthlyRepayment(),\r\n self.ProviderLow.CalculationTotalRepayment(),\r\n self.HowMuch(),\r\n self.HowLong(),\r\n self.ProviderLow.RepresentativeExample()\r\n ));\r\n\r\n self.ProviderModerate.TokenizedRepresentativeExample(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTokenizedRepresentativeExample(\r\n self.ProviderModerate.CalculationTierPercentage(),\r\n self.ProviderModerate.CalculationMonthlyRepayment(),\r\n self.ProviderModerate.CalculationTotalRepayment(),\r\n self.HowMuch(),\r\n self.HowLong(),\r\n self.ProviderModerate.RepresentativeExample()\r\n ));\r\n\r\n self.ProviderHigh.TokenizedRepresentativeExample(\r\n CONFUSEDCARFINANCECALCULATORAPP.Helper.obtainTokenizedRepresentativeExample(\r\n self.ProviderHigh.CalculationTierPercentage(),\r\n self.ProviderHigh.CalculationMonthlyRepayment(),\r\n self.ProviderHigh.CalculationTotalRepayment(),\r\n self.HowMuch(),\r\n self.HowLong(),\r\n self.ProviderHigh.RepresentativeExample()\r\n ));\r\n\r\n // log mi\r\n CONFUSEDCARFINANCECALCULATORAPP.submitCalculation(\r\n self.ProviderLow,\r\n self.ProviderModerate,\r\n self.ProviderHigh,\r\n self.HowMuch(),\r\n self.HowLong()\r\n );\r\n\r\n return true;\r\n };\r\n\r\n // on Provider Low Title\r\n self.onProviderLowTitle = function () {\r\n ns.Utils.ShowProviderLowSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderLow, false);\r\n };\r\n\r\n // on Provider Moderate Title\r\n self.onProviderModerateTitle = function () {\r\n ns.Utils.ShowProviderModerateSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderModerate, false);\r\n };\r\n\r\n // on Provider High Title\r\n self.onProviderHighTitle = function () {\r\n ns.Utils.ShowProviderHighSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderHigh, false);\r\n };\r\n\r\n // provider title selected on mobile\r\n $(ns.Elements.ProviderTitleOnMobile).change(function () {\r\n switch ($(ns.Elements.ProviderTitleOnMobile).val()) {\r\n case ns.Constants.ProviderLowTitleOnMobile:\r\n ns.Utils.ShowProviderLowSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderLow, true);\r\n break;\r\n case ns.Constants.ProviderModerateTitleOnMobile:\r\n ns.Utils.ShowProviderModerateSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderModerate, true);\r\n break;\r\n case ns.Constants.ProviderHighTitleOnMobile:\r\n ns.Utils.ShowProviderHighSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderHigh, true);\r\n break;\r\n default:\r\n ns.Utils.ShowProviderLowSection();\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider(ns.Constants.ProviderLow, true);\r\n }\r\n });\r\n\r\n // on Start Application\r\n $(ns.Elements.StartApplicationButton).click(function (e) {\r\n e.preventDefault();\r\n\r\n // get link\r\n var startApplicationLink = self.detokenizeLink($(ns.Elements.StartApplicationButton).attr('href'));\r\n\r\n // log mi\r\n CONFUSEDCARFINANCECALCULATORAPP.submitClickthrough('startapplication', startApplicationLink);\r\n\r\n // open link\r\n window.open(startApplicationLink, '_self');\r\n });\r\n\r\n\r\n // on Get A Quote\r\n $(ns.Elements.GetAQuoteButton).click(function (e) {\r\n e.preventDefault();\r\n\r\n // get link\r\n var getAQuoteLink = self.detokenizeLink($(ns.Elements.GetAQuoteButton).attr('href'));\r\n\r\n // log mi\r\n CONFUSEDCARFINANCECALCULATORAPP.submitClickthrough('getaquote', getAQuoteLink);\r\n\r\n // open link\r\n window.open(getAQuoteLink, '_self');\r\n });\r\n\r\n // detokenize link\r\n self.detokenizeLink = function (link) {\r\n return link\r\n .replace(ns.Tokens.HowMuch, self.HowMuch())\r\n .replace(ns.Tokens.HowLong, self.HowLong());\r\n };\r\n\r\n // monthly repayment whole number\r\n self.MonthlyRepaymentWholePart = function (calculation) {\r\n return ns.Utils.NumberWithCommas(calculation().toFixed(2).toString().split('.')[0]);\r\n };\r\n\r\n // monthly repayment fraction number\r\n self.MonthlyRepaymentDecimalPart = function (calculation) {\r\n return calculation().toFixed(2).toString().split('.')[1];\r\n };\r\n\r\n // tier percentage format\r\n self.TierPercentageFormat = function (calculation) {\r\n return ns.Utils.NumberWithDecimalPlace(calculation());\r\n };\r\n\r\n };\r\n\r\n // set up car finance calculator form\r\n if ($(ns.Elements.CarFinanceCalculatorWidget).length > 0) {\r\n\r\n var carFinanceCalculatorForm = new CONFUSEDCARFINANCECALCULATORAPP.CarFinanceCalculatorForm();\r\n carFinanceCalculatorForm.Initialise();\r\n\r\n }\r\n\r\n})(CONFUSEDCARFINANCECALCULATORAPP, newrelic, jQuery);\r\n\r\n\r\n\r\n","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDCARFINANCECALCULATORAPP = CONFUSEDCARFINANCECALCULATORAPP || {},\r\n Confused = Confused || {};\r\n\r\nCONFUSEDCARFINANCECALCULATORAPP.Helper = CONFUSEDCARFINANCECALCULATORAPP.Helper || {};\r\n\r\n(function (ns, $) {\r\n 'use strict';\r\n\r\n // tokens\r\n ns.Tokens = {\r\n AMOUNT: '[AMOUNT]',\r\n MONTHS: '[MONTHS]',\r\n RATE: '[RATE]',\r\n MONTHLYREPAYMENT: '[MONTHLYREPAYMENT]',\r\n TOTALREPAYMENT: '[TOTALREPAYMENT]'\r\n };\r\n\r\n // utils functions\r\n ns.Utils = {\r\n \r\n // replace all\r\n ReplaceAll: function (target, search, replacement) {\r\n return target.split(search).join(replacement);\r\n }\r\n };\r\n\r\n // validate calculation data\r\n ns.validateCalculationData = function(howMuch, howLong, providerLow, providerModerate, providerHigh) {\r\n\r\n if (!$.isNumeric(howMuch) || !$.isNumeric(howLong) ||\r\n howMuch < 1000 || howMuch > 36000 ||\r\n howLong < 12 || howLong > 120) {\r\n return false;\r\n }\r\n\r\n if (!ns.validateCalculationProvider(providerLow) ||\r\n !ns.validateCalculationProvider(providerModerate) ||\r\n !ns.validateCalculationProvider(providerHigh)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // validate calculation provider\r\n ns.validateCalculationProvider = function(provider) {\r\n\r\n if (provider == null || !provider.RepresentativeExample()) {\r\n return false;\r\n }\r\n\r\n if (!$.isNumeric(provider.Tier1000To1999Percentage()) ||\r\n !$.isNumeric(provider.Tier2000To2999Percentage()) ||\r\n !$.isNumeric(provider.Tier3000To4999Percentage()) ||\r\n !$.isNumeric(provider.Tier5000To7499Percentage()) ||\r\n !$.isNumeric(provider.Tier7500To19999Percentage()) ||\r\n !$.isNumeric(provider.Tier20000To36000Percentage())) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // obtain tier percentage\r\n ns.obtainTierPercentage = function (howMuch, provider) {\r\n var iHowMuch = parseInt(howMuch);\r\n\r\n if (iHowMuch >= 1000 && iHowMuch <= 1999) {\r\n return provider.Tier1000To1999Percentage();\r\n }\r\n else if (iHowMuch >= 2000 && iHowMuch <= 2999) {\r\n return provider.Tier2000To2999Percentage();\r\n }\r\n else if (iHowMuch >= 3000 && iHowMuch <= 4999) {\r\n return provider.Tier3000To4999Percentage();\r\n }\r\n else if (iHowMuch >= 5000 && iHowMuch <= 7499) {\r\n return provider.Tier5000To7499Percentage();\r\n }\r\n else if (iHowMuch >= 7500 && iHowMuch <= 19999) {\r\n return provider.Tier7500To19999Percentage();\r\n }\r\n else if (iHowMuch >= 20000 && iHowMuch <= 36000) {\r\n return provider.Tier20000To36000Percentage();\r\n } else {\r\n return null;\r\n }\r\n };\r\n\r\n // obtain monthly repayment\r\n ns.obtainMonthlyRepayment = function (tierPercentage, howMuch, howLong) {\r\n var fTierPercentage = parseFloat(tierPercentage);\r\n var iHowMuch = parseInt(howMuch);\r\n var iHowLong = parseInt(howLong);\r\n\r\n // Monthly repayment calculation as per #146738...\r\n var monthlyRate = Math.pow(((fTierPercentage / 100) + 1), (1 / 12)) - 1;\r\n var x = (1 / monthlyRate) - (1 / (monthlyRate * Math.pow((monthlyRate + 1), iHowLong)));\r\n var monthlyPayment = iHowMuch / x;\r\n\r\n return monthlyPayment;\r\n };\r\n\r\n // obtain total repayment\r\n ns.obtainTotalRepayment = function (monthlyRepayment, howLong) {\r\n var fMonthlyRepayment = parseFloat(monthlyRepayment).toFixed(2);\r\n var iHowLong = parseInt(howLong);\r\n\r\n return fMonthlyRepayment * iHowLong;\r\n };\r\n\r\n // obtain tokenized representative example\r\n ns.obtainTokenizedRepresentativeExample = function (tierPercentage, monthlyRepayment, totalRepayment,\r\n howMuch, howLong, representativeExample) {\r\n\r\n // tokenize the representative example\r\n var tokenizedRepresentativeExample = ns.Utils.ReplaceAll(representativeExample, ns.Tokens.RATE, CONFUSEDCARFINANCECALCULATORAPP.Utils.NumberWithDecimalPlace(tierPercentage));\r\n\r\n tokenizedRepresentativeExample = ns.Utils.ReplaceAll(tokenizedRepresentativeExample, ns.Tokens.MONTHLYREPAYMENT, CONFUSEDCARFINANCECALCULATORAPP.Utils.NumberWithCommas(monthlyRepayment.toFixed(2)));\r\n tokenizedRepresentativeExample = ns.Utils.ReplaceAll(tokenizedRepresentativeExample, ns.Tokens.TOTALREPAYMENT, CONFUSEDCARFINANCECALCULATORAPP.Utils.NumberWithCommas(totalRepayment.toFixed(2)));\r\n tokenizedRepresentativeExample = ns.Utils.ReplaceAll(tokenizedRepresentativeExample, ns.Tokens.AMOUNT, CONFUSEDCARFINANCECALCULATORAPP.Utils.NumberWithCommas(howMuch));\r\n tokenizedRepresentativeExample = ns.Utils.ReplaceAll(tokenizedRepresentativeExample, ns.Tokens.MONTHS, howLong);\r\n\r\n return tokenizedRepresentativeExample;\r\n };\r\n\r\n\r\n\r\n}(CONFUSEDCARFINANCECALCULATORAPP.Helper, jQuery));","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDCARFINANCECALCULATORAPP = CONFUSEDCARFINANCECALCULATORAPP || {};\r\n\r\n(function () {\r\n 'use strict';\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitCalculation = function (\r\n providerLow, providerModerate, providerHigh, howMuch, howLong) {\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitPageEvent({\r\n EventType: 'carfinancecalculator:calculation:clicked',\r\n EventInfo: {\r\n 'ProviderLowRate': providerLow.CalculationTierPercentage(),\r\n 'ProviderLowMonthlyRepayment': providerLow.CalculationMonthlyRepayment(),\r\n 'ProviderLowTotalRepayment': providerLow.CalculationTotalRepayment(),\r\n 'ProviderModerateRate': providerModerate.CalculationTierPercentage(),\r\n 'ProviderModerateMonthlyRepayment': providerModerate.CalculationMonthlyRepayment(),\r\n 'ProviderModerateTotalRepayment': providerModerate.CalculationTotalRepayment(),\r\n 'ProviderHighRate': providerHigh.CalculationTierPercentage(),\r\n 'ProviderHighMonthlyRepayment': providerHigh.CalculationMonthlyRepayment(),\r\n 'ProviderHighTotalRepayment': providerHigh.CalculationTotalRepayment(),\r\n 'Amount': howMuch,\r\n 'Months': howLong\r\n }\r\n });\r\n };\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitClickthrough = function (name, link) {\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitPageEvent({\r\n EventType: 'carfinancecalculator:' + name + ':clicked',\r\n EventInfo: {\r\n 'Link': link\r\n }\r\n });\r\n };\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitProvider = function (providerType, isDropdown) {\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitPageEvent({\r\n EventType: 'carfinancecalculator:provider:clicked',\r\n EventInfo: {\r\n 'ProviderType': providerType,\r\n 'IsDropdown': isDropdown\r\n }\r\n });\r\n };\r\n\r\n CONFUSEDCARFINANCECALCULATORAPP.submitPageEvent = function (eventInfo) {\r\n CONFUSEDCMS.services.MiService().pageEvent(eventInfo);\r\n };\r\n\r\n}());","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CSSCONSTANTS = CSSCONSTANTS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.expandingBands = function () {\r\n \r\n var $expandingBandToggleContainer = $('.band-toggle-container');\r\n var $expandingBandToggle = $expandingBandToggleContainer.find('.band-toggle');\r\n var $expandingBandToggleSection = $expandingBandToggleContainer.next('.band--toggle-section');\r\n\r\n $expandingBandToggle.on('click',function (e) {\r\n e.preventDefault();\r\n if($expandingBandToggle.hasClass('band-toggle--open')) {\r\n $expandingBandToggle.removeClass('band-toggle--open');\r\n $expandingBandToggle.addClass('band-toggle--closed');\r\n $expandingBandToggleSection.slideUp();\r\n $expandingBandToggleSection.addClass('band--toggle-section--closed');\r\n }\r\n else {\r\n $expandingBandToggle.removeClass('band-toggle--closed');\r\n $expandingBandToggle.addClass('band-toggle--open');\r\n $expandingBandToggleSection.slideDown();\r\n $expandingBandToggleSection.removeClass('band--toggle-section--closed');\r\n } \r\n });\r\n };\r\n\r\n\r\n})(window.jQuery);\r\n\r\n\r\n","var CONFUSEDCMS = CONFUSEDCMS || {},\r\n CONFUSEDWEBSITE = CONFUSEDWEBSITE || {},\r\n CONFUSEDCORE = CONFUSEDCORE || {},\r\n CSSCONSTANTS = CSSCONSTANTS || {};\r\n\r\n(function ($) {\r\n\r\n //setup expert search module (google custom search configuration)\r\n (function () {\r\n var el = document.getElementById('expertSearch');\r\n if (el) {\r\n var searchDetails = {\r\n searchFormId: 'expertSearch',\r\n buttonClass: 'contextual-search__submit--expertSearch',\r\n searchTextId: 'expert-help-question',\r\n customSearchKeyId: 'googleCustomKey',\r\n invalidInputSelector: '#query-error'\r\n };\r\n\r\n CONFUSEDWEBSITE.setupSearch(searchDetails);\r\n }\r\n })();\r\n\r\n //setup help header module (google custom search configuration)\r\n (function () {\r\n var el = document.getElementById('helpHeader');\r\n if (el) {\r\n var searchDetails = {\r\n searchFormId: 'helpHeader',\r\n buttonClass: 'searchTextHelp',\r\n searchTextId: 'searchTextHelp',\r\n customSearchKeyId: 'googleCustomKey',\r\n invalidInputSelector: '#query-error'\r\n };\r\n\r\n CONFUSEDWEBSITE.setupSearch(searchDetails);\r\n }\r\n\r\n })();\r\n\r\n\r\n\r\n $(function () {\r\n var pageUrl = window.location.href;\r\n\r\n // RUN COOKIE POPUP WIDGET\r\n var cookiePolicyWidget = window.Confused.CookiePolicyWidget;\r\n cookiePolicyWidget.run();\r\n\r\n //CONFUSEDCORE.MI.MiListener.postLogSession('LogNewSession');\r\n // TRIGGER NEW SESSION CALL IN MI - WAIT FOR CALLBACK FROM SESSION CALL THEN TRIGGER COOKIE POPUP SHOWN EVENT\r\n var miListener = CONFUSEDCORE.MI.MiListener;\r\n miListener.postPageView('LogPageView', { page: pageUrl, referer: document.referrer }, function () {\r\n if (cookiePolicyWidget.wasCookiePopupShown()) {\r\n miListener.postEvent('CookiePopupShown');\r\n }\r\n });\r\n\r\n //CONFUSEDCORE.MI.MiListener.pageView($('body').data('mi-pagename'));\r\n CONFUSEDCMS.contactUsFormSetup($);\r\n CONFUSEDWEBSITE.expandingPanel();\r\n \r\n CONFUSEDWEBSITE.responsiveTables();\r\n\r\n CONFUSEDWEBSITE.setupOverlaps();\r\n\r\n CONFUSEDCMS.setupProductDrivers();\r\n\r\n CONFUSEDCMS.responsiveTabs();\r\n\r\n CONFUSEDCMS.setupProviderList();\r\n\r\n CONFUSEDCMS.setupProductTestimonials();\r\n\r\n CONFUSEDCMS.expandingBands();\r\n\r\n CONFUSEDWEBSITE.setupEqualizeHeights();\r\n\r\n CONFUSEDCMS.setupProductCtas();\r\n\r\n if ($('div.mot-checker').length > 0) {\r\n var motChecker = new CONFUSEDCMS.VehicleDetails.MotChecker();\r\n var $form = $('.js-mot-checker');\r\n motChecker.InitialiseModule($form);\r\n CONFUSEDCMS.setUpVehicleDetailsCheckerValidation($form);\r\n }\r\n\r\n if ($('.img--infographic--animated').length > 0) {\r\n CONFUSEDCMS.priceIndex();\r\n }\r\n\r\n if ($('div.owl-carousel').length > 0) {\r\n CONFUSEDCMS.carousel($);\r\n }\r\n\r\n if ($('.cms-tabs__tab-list').length > 0) {\r\n CONFUSEDCMS.tabs($);\r\n }\r\n\r\n CONFUSEDCMS.postCodeFromURL();\r\n \r\n\r\n });\r\n})(window.jQuery);","var CONFUSEDCORPORATE = CONFUSEDCORPORATE || {},\r\n CONFUSEDWEBSITE = CONFUSEDWEBSITE || {},\r\n CONFUSEDCORE = CONFUSEDCORE || {};\r\n\r\n(function ($) {\r\n\r\n this.displayMainForm = function () {\r\n\r\n var self = this;\r\n\r\n // If not logged in, display Log In panel\r\n if (!self.IsAuthenticatedUser) {\r\n $('#LogInBanner').show();\r\n }\r\n\r\n $('#frmDetails').show();\r\n $('#MessageDetails').show();\r\n }\r\n\r\n this.redirectToLogin = function() {\r\n\r\n // Get the value out of the product drop-down\r\n var product = $('#querySelect').val();\r\n\r\n // Get the value out of the more information drop-down (if any)\r\n var moreInformation = $('#MoreInformation').val();\r\n\r\n // Get the url from the anchor\r\n var loginLink = $('#Login_Link').attr('href');\r\n\r\n // Add the first\r\n loginLink += '%3Fproduct%3D' + product;\r\n\r\n // Add the more information drop down if present\r\n if (moreInformation !== \"\") {\r\n loginLink += '%26moreInformation%3D' + moreInformation;\r\n }\r\n\r\n // Perform the redirect\r\n window.location.href = loginLink;\r\n }\r\n\r\n $(document).ready(function () {\r\n\r\n var querySelect = $('#querySelect');\r\n var moreInformationSelect = $('#MoreInformation');\r\n\r\n function DisplayMainFormInformation() {\r\n\r\n var self = this;\r\n\r\n // If not logged in, display Log In panel\r\n if (!self.IsAuthenticatedUser) {\r\n $('#LogInBanner').show();\r\n }\r\n\r\n $('#frmDetails').show();\r\n $('#MessageDetails').show();\r\n\r\n }\r\n\r\n // Set up event for when drop-down is selected\r\n $(querySelect).change(function(data) {\r\n // If the value of what has been selected required more information\r\n var selectionOption = $('option:selected', querySelect);\r\n\r\n if (selectionOption.attr('data-more-info') == \"True\") {\r\n $('#MoreInformationSection').show();\r\n } else {\r\n $('#MoreInformationSection').hide();\r\n displayMainForm();\r\n }\r\n });\r\n\r\n $(moreInformationSelect).change(function(data) {\r\n displayMainForm();\r\n });\r\n\r\n $('#Login_Link').on('click', function(e) {\r\n\r\n // Prevent the anchor redirecting\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n redirectToLogin();\r\n\r\n });\r\n\r\n $('#btnSubmit').click(function() {\r\n\r\n if ($('#frmBody').valid()\r\n && $('#title').valid()) {\r\n\r\n // Create the json object containing the data to send\r\n var DOB_Day = $('#daySelect').val();\r\n var DOB_Month = $('#monthSelect').val();\r\n var DOB_Year = $('#yearSelect').val();\r\n\r\n var DOB = DOB_Day + '/' + DOB_Month + '/' + DOB_Year;\r\n\r\n var formInformation = {\r\n \"Product\": $('#querySelect').val(),\r\n \"MoreInformation\": $('#MoreInformation').val(),\r\n \"Title\": $('#title').val(),\r\n \"FirstName\": $('#FirstName').val(),\r\n \"Surname\": $('#Surname').val(),\r\n \"EmailAddress\": $('#Email').val(),\r\n \"Postcode\": $('#Postcode').val(),\r\n \"DateOfBirth\": DOB,\r\n \"ContactPhoneQuestion\": $('input[name=contactByPhone]:checked').val(),\r\n \"ContactPhoneNumber\": $('#phone').val(),\r\n \"HasPurchased\": $('#hasPurchased').val(),\r\n \"QuerySubject\": $('#subject').val(),\r\n \"QueryDescription\": $('#messageContents').val(),\r\n \"HttpAttributeReturnUrl\": $('#returnUrl').val(),\r\n \"HttpAttributePriority\": $('#HttpAttributePriority').val(),\r\n \"HttpAttributeOrigin\": $('#HttpAttributeOrigin').val(),\r\n \"HttpAttributeExternal\": $('#HttpAttributeExternal').val()\r\n\r\n\r\n };\r\n\r\n $.ajax({\r\n url: '/api/contact-us/submit',\r\n type: 'POST',\r\n processData: false,\r\n contentType: 'application/json; charset=utf-8',\r\n dataType: 'json',\r\n data: JSON.stringify(formInformation),\r\n success: function(result) {\r\n\r\n if (result.Success) {\r\n // Redirect to configured Thank You page\r\n var returnUrl = $('#returnUrl').val();\r\n window.location.href = returnUrl;\r\n } else {\r\n // Display the error panel\r\n $('#ErrorBanner').show();\r\n $(document).scrollTop($(\"#ErrorBanner\").offset().top);\r\n }\r\n }\r\n });\r\n } else {\r\n var height = $(window).height();\r\n $(document).scrollTop($(\".label-error:visible:first\").offset().top - (height / 2));\r\n }\r\n });\r\n });\r\n})(window.jQuery);\r\n","var CONFUSEDCMS = CONFUSEDCMS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.carousel = function () {\r\n\r\n var owlCarouselWrapper = $('.owl-carousel');\r\n owlCarouselWrapper.owlCarousel({\r\n margin: 10,\r\n nav: true,\r\n dots: true,\r\n loop: true,\r\n items: 1,\r\n responsive: {\r\n 0: {\r\n stagePadding: 40\r\n },\r\n 901: {\r\n stagePadding: 0\r\n }\r\n }\r\n });\r\n\r\n };\r\n})(window.jQuery);","var CONFUSEDCMS = CONFUSEDCMS || {};\r\n\r\n(function ($) {\r\n\r\n CONFUSEDCMS.tabs = function () {\r\n\r\n var tabs = $(\".cms-tabs__tab-list\"),\r\n tabItem = tabs.find(\"li\"),\r\n tabItems = tabItem.length,\r\n tabsLink = tabs.find(\"a\"),\r\n contentPanel = $(\".cms-tabs__content__panel\"),\r\n activeClass = (\"active\");\r\n\r\n\r\n tabs.addClass(\"cms-tabs__tab-list--\" + tabItems + \"-col\");\r\n\r\n tabsLink.click(function () {\r\n var tabNumber = $(this).attr(\"data-tab\");\r\n tabsLink.removeClass(activeClass);\r\n $(this).addClass(activeClass);\r\n\r\n contentPanel.removeClass(activeClass);\r\n $(\"#tab-\" + tabNumber).addClass(activeClass);\r\n\r\n return false;\r\n });\r\n\r\n }; \r\n})(window.jQuery);","window.confused = window.confused || {};\r\n\r\nconfused.fuelCost = (function ($, fuelcost) {\r\n\r\n var $fuelCostCalculator;\r\n var $userInputReg;\r\n\r\n var carInfo = {\r\n reg: \"\",\r\n make: \"\",\r\n model: \"\",\r\n mpg: \"\"\r\n };\r\n\r\n var $costInfoFields = {};\r\n var progress = 0;\r\n var pageTransition;\r\n var pageTransitionState = [\"panel1\", \"panel2\", \"panel3\", \"panel4\"];\r\n var numberOfLtrToGallon = 4.545;\r\n\r\n /* ----------Car Lookup----------*/\r\n function findCarClickEvent() {\r\n $userInputReg = $fuelCostCalculator.find(\"#RegNumber\").val();\r\n\r\n if (validRegNumber($userInputReg)) {\r\n hideErrors();\r\n clearPrefilledCarLookupValues();\r\n $fuelCostCalculator.find(\"#RegLookupAjaxSpinner\").show();\r\n carRegLookup($userInputReg);\r\n } else {\r\n $fuelCostCalculator.find(\"#regerror\").slideDown(300);\r\n }\r\n }\r\n\r\n function updateCarDetails() {\r\n setText(\"#VehicleResultReg\", carInfo.reg.toUpperCase());\r\n setText(\"#VehicleMake\", carInfo.make.toUpperCase());\r\n setText(\"#VehicleModel\", carInfo.model.toUpperCase());\r\n }\r\n\r\n function carLookupSuccess(carResult) {\r\n //do something with car results\r\n carInfo.reg = $userInputReg;\r\n carInfo.make = carResult.CarMake;\r\n carInfo.model = carResult.CarModel;\r\n carInfo.mpg = carResult.MpgValue;\r\n\r\n //Update Mpg field\r\n $fuelCostCalculator.find(\"#MpgValue\").val(carInfo.mpg);\r\n\r\n //prefill the values\r\n updateCarDetails();\r\n pageTransition.next();\r\n }\r\n\r\n function carLookupFailure() {\r\n //No result found, show error message\r\n $fuelCostCalculator.find(\"#searcherror\").slideDown(300);\r\n $fuelCostCalculator.find(\"#regerror\").slideUp(300);\r\n $fuelCostCalculator.find(\"#RegLookupAjaxSpinner\").hide();\r\n }\r\n\r\n function carRegLookup(registration) {\r\n\r\n var jsonData = \"{'registrationNumber': '\" + registration + \"'}\";\r\n\r\n $.ajax({\r\n url: \"/api/GetVehicleFuelCostDetails\",\r\n cache: false,\r\n type: \"POST\",\r\n contentType: \"application/json\",\r\n dataType: \"json\",\r\n data: jsonData,\r\n success: function (result) {\r\n if (result.VehicleResultFound) {\r\n // toggle text for assume/estimated mpg value. \r\n if (result.VehicleValuesAssumed === true) {\r\n $fuelCostCalculator.find(\".mpgEstimated\").hide();\r\n $fuelCostCalculator.find(\".mpgAssumed\").show();\r\n } else {\r\n $fuelCostCalculator.find(\".mpgEstimated\").show();\r\n $fuelCostCalculator.find(\".mpgAssumed\").hide();\r\n }\r\n $fuelCostCalculator.find(\"#RegLookupAjaxSpinner\").hide();\r\n carLookupSuccess(result);\r\n } else {\r\n carLookupFailure();\r\n }\r\n },\r\n error: function () {\r\n carLookupFailure();\r\n }\r\n });\r\n }\r\n\r\n /* ----------Validation----------*/\r\n\r\n function hideErrors() {\r\n $fuelCostCalculator.find(\".error\").hide();\r\n }\r\n\r\n function validRegNumber(regNumber) {\r\n if (regNumber === \"\" || !regNumber.match(\"^[a-zA-Z0-9 -]{2,10}$\")) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n //Checks against numeric fields. Allows a single or no decimal point and no letters. \r\n function validNumberValue(numericInput) {\r\n if (numericInput === \"\" || !numericInput.match(\"^[0-9]*[\\.]{0,1}[0-9]*$\")) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n //Deals with checking number inputs. If not valid and an error message is available it will show that message.\r\n function numberInputCheck() {\r\n var $this = $(this);\r\n var nextEl = $this.next();\r\n if (!validNumberValue($this.val())) {\r\n if (nextEl.hasClass(\"error\")) {\r\n $this.next().show();\r\n }\r\n //invalid\r\n return false;\r\n } else {\r\n if (nextEl.hasClass(\"error\")) {\r\n $this.next().hide();\r\n }\r\n //valid\r\n return true;\r\n }\r\n }\r\n\r\n /* ----------Prefill and Cleanup----------*/\r\n\r\n //Clears \r\n function clearPrefilledCarLookupValues() {\r\n $.each(carInfo, function (i) {\r\n carInfo[i] = \"\";\r\n });\r\n updateCarDetails();\r\n }\r\n\r\n function setText(el, text) {\r\n $fuelCostCalculator.find(el).text(text);\r\n }\r\n\r\n function calculateResult() {\r\n $costInfoFields.fuel.val($(\"#fuelCostPerLitre\").val());\r\n $costInfoFields.annualMileage.val($(\"#AverageMilesPerYear\").val());\r\n\r\n var costPerGallon = $costInfoFields.fuel.val() * numberOfLtrToGallon;\r\n var numOfGallonsForAnnualMileage = $costInfoFields.annualMileage.val() / carInfo.mpg;\r\n\r\n //Calculate the costs and store them in a cost object.\r\n var annualResult = costPerGallon * numOfGallonsForAnnualMileage;\r\n\r\n var costs = {\r\n annualResult: annualResult.toFixed(2),\r\n monthlyResult: (annualResult / 12).toFixed(2),\r\n weeklyResult: (annualResult / 52).toFixed(2)\r\n };\r\n\r\n prefillResultsPage(costs);\r\n\r\n }\r\n\r\n function prefillResultsPage(costs) {\r\n //opening sentence of prices page\r\n setText(\"#ResultsMake\", carInfo.make);\r\n setText(\"#ResultsModel\", carInfo.model);\r\n setText(\"#ResultsAnnualMileage\", $costInfoFields.annualMileage.val());\r\n setText(\"#ResultsFuelCost\", \"£\" + $costInfoFields.fuel.val());\r\n\r\n //Results\r\n setText(\"#annualCostResult\", \"£\" + costs.annualResult);\r\n setText(\"#monthlyCostResult\", \"£\" + costs.monthlyResult);\r\n setText(\"#weeklyCostResult\", \"£\" + costs.weeklyResult);\r\n }\r\n\r\n function otherQuestionsPageIsValid() {\r\n var mpgIsValid = numberInputCheck.apply($(\"#MpgValue\"), []);\r\n var avgMilesIsValid = numberInputCheck.apply($(\"#AverageMilesPerYear\"), []);\r\n var fuelCostIsValid = numberInputCheck.apply($(\"#fuelCostPerLitre\"), []);\r\n var isValid = mpgIsValid && avgMilesIsValid && fuelCostIsValid;\r\n return isValid;\r\n }\r\n\r\n //this will ensure the two fuelCost related input values are kept in sync\r\n function syncFuelCosts() {\r\n var $this = $(this);\r\n var newVal = parseFloat($this.val());\r\n if (numberInputCheck.apply($this, [])) {\r\n $(\".fuelCostInput\").val(newVal.toFixed(2));\r\n }\r\n }\r\n\r\n //this will ensure the two fuelCost related input values are kept in sync\r\n function syncMpgCosts() {\r\n var $this = $(this);\r\n var newMpgVal = parseFloat($this.val());\r\n if (numberInputCheck.apply($this, [])) {\r\n carInfo.mpg = newMpgVal;\r\n }\r\n }\r\n\r\n function updateResults() {\r\n if (numberInputCheck.apply($(\"#fuelCostToggle\"), [])) {\r\n calculateResult();\r\n }\r\n }\r\n\r\n function changeFuelCost(diff) {\r\n var newVal = parseFloat($(\"#fuelCostToggle\").val()) + diff;\r\n $(\"#fuelCostToggle\").val(newVal.toFixed(2)).trigger(\"change\");\r\n }\r\n\r\n /* ----------Document ready----------*/\r\n $(document).ready(function () {\r\n\r\n //cache root element of widget to perform searches on.\r\n $fuelCostCalculator = $(\"#FuelCostCalculator\");\r\n\r\n /*----------SetUp PageTransition function.----------*/\r\n // This fuction will deal with the transition from page to page, mainly dealing with the animation\r\n // The animation performed is dependant on the \"progress\" variable. 0 being the first page, 1 being the second up to 3 being the results. \r\n pageTransition = (function (transition) {\r\n\r\n //the container for the back, try again and continue buttons\r\n var $navBar = $fuelCostCalculator.find(\".page-nav\");\r\n\r\n //the widget containing the social media links\r\n var $shareWidget = $fuelCostCalculator.find(\"#widget-share\");\r\n\r\n transition.next = function () {\r\n movePages(function () { progress++; });\r\n };\r\n\r\n transition.previous = function () {\r\n movePages(function () { progress--; });\r\n };\r\n\r\n //takes the user back to the first page and clears the most recent car lookup info.\r\n transition.reset = function () {\r\n progress = 0;\r\n clearPrefilledCarLookupValues();\r\n updateCarDetails();\r\n animateTransition();\r\n\r\n $fuelCostCalculator.find(\"#panel4\").fadeOut({\r\n complete: function () {\r\n $fuelCostCalculator.find(\"#panel1\").fadeIn();\r\n }\r\n });\r\n };\r\n\r\n function toggleFade(shouldBeShown) {\r\n var currentlyVisble = $(this).is(\":visible\");\r\n\r\n if (!currentlyVisble && shouldBeShown) {\r\n $(this).fadeIn();\r\n return;\r\n }\r\n\r\n if (currentlyVisble && !shouldBeShown) {\r\n $(this).fadeOut();\r\n return;\r\n }\r\n }\r\n\r\n function animateTransition() {\r\n toggleFade.apply($navBar, [(progress > 0 && progress !== 3)]); //hide nav bar on first page and results page\r\n toggleFade.apply($navBar.find(\".TryAgain-Button\"), [(progress === 1)]); //show try again button on second page. \r\n toggleFade.apply($navBar.find(\".Back-Button\"), [(progress > 1)]); //show Back button after the second page. \r\n toggleFade.apply($navBar.find(\".Continue-Button\"), [(progress === 1)]); //Show continue button on second page\r\n toggleFade.apply($shareWidget, [(progress === 0 || progress === 3)]); //show share widget on first and last page\r\n toggleFade.apply($navBar.find(\".calculatButtonDiv\"), [(progress === 2)]); //show calculate button on third page. \r\n toggleFade.apply($fuelCostCalculator.find(\".recalculatButtonDiv\"), [(progress === 3)]); //Show recalc button on the results page\t\t\t\r\n }\r\n\r\n function movePages(action) {\r\n function showNewPage() {\r\n action();\r\n animateTransition();\r\n //Show next page regardless of page specific features\r\n $fuelCostCalculator.find(\"#\" + pageTransitionState[progress]).fadeIn();\r\n }\r\n\r\n $fuelCostCalculator.find(\"#\" + pageTransitionState[progress]).fadeOut({ complete: showNewPage });\r\n }\r\n\r\n return transition;\r\n }({}));\r\n\r\n //Set up required cost calculation field information\r\n $costInfoFields = {\r\n mpg: $fuelCostCalculator.find(\"#mpg\"),\r\n annualMileage: $fuelCostCalculator.find(\"#mileage\"),\r\n fuel: $fuelCostCalculator.find(\"#fuel\")\r\n };\r\n\r\n //This stops multiple server requests being made or page skips occuring.\r\n function preventDoubleClick() {\r\n var $this = $(this);\r\n if ($this.attr(\"disabled\") !== true) {\r\n $this.attr(\"disabled\", true);\r\n setTimeout(function () {\r\n $this.attr(\"disabled\", false);\r\n }, 1000);\r\n }\r\n }\r\n\r\n $fuelCostCalculator.find(\"button.nav-button, #findCar\").click(preventDoubleClick);\r\n\r\n //event handlers\r\n $fuelCostCalculator.find(\"#findCar\").click(findCarClickEvent);\r\n $fuelCostCalculator.find(\"#RegNumber\").keyup(function (e) {\r\n var key = e.which;\r\n if (key === 13) {\r\n findCarClickEvent();\r\n }\r\n });\r\n $fuelCostCalculator.find(\".Continue-Button\").click(pageTransition.next);\r\n $fuelCostCalculator.find(\".Back-Button, .TryAgain-Button\").click(pageTransition.previous);\r\n\r\n $fuelCostCalculator.find(\"#Calculate\").click(function () {\r\n if (otherQuestionsPageIsValid()) {\r\n calculateResult();\r\n pageTransition.next();\r\n }\r\n });\r\n $fuelCostCalculator.find(\"#Reset\").click(pageTransition.reset);\r\n $fuelCostCalculator.find(\"#AverageMilesPerYear, #fuelCostPerLitre\").blur(numberInputCheck);\r\n $fuelCostCalculator.find(\".fuelCostInput\").change(syncFuelCosts);\r\n $fuelCostCalculator.find(\"#fuelCostToggle\").change(updateResults);\r\n $fuelCostCalculator.find(\"#MpgValue\").blur(syncMpgCosts);\r\n\r\n $fuelCostCalculator.find(\"#increaseFuelCost\").click(function () {\r\n changeFuelCost(0.01);\r\n });\r\n\r\n $fuelCostCalculator.find(\"#decreaseFuelCost\").click(function () {\r\n changeFuelCost(-0.01);\r\n });\r\n\r\n return fuelcost;\r\n });\r\n\r\n}(jQuery, {}));","var CONFUSEDCMS = CONFUSEDCMS || {};\r\n\r\n(function ($) {\r\n\r\n\tCONFUSEDCMS.postCodeFromURL = function () {\r\n\r\n\t\tif (typeof URLSearchParams === 'function') {\r\n\t\t\tvar input = jQuery('input[type=\"text\"].js-get-a-quote-input');\r\n\t\t\tif (input) {\r\n\t\t\t\tvar params = new window.URLSearchParams(window.location.search);\r\n\t\t\t\tinput.val(params.get('postcode'));\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n})(window.jQuery);\r\n"]}