1/* 2 Main ChurchInsight shop template Javascript/JQuery file. 3 WARNING - do not edit this file unless you know exactly what you are doing. 4 If you need advice, contact Endis/ChurchInsight Support. 5*/ 6 7// This file runs after the web-page has loaded, as there is a "defer" attribute on the <script> tag in the HTML header. 8// The preloaded JQuery version is V1.10.2. 9 10$(document).ready(function () 11{ 'use strict'; 12 13// ############# Configuration settings ############### 14var sPath = '/Images/Content/2414/Templates/47288/images/'; // The template path. Must be updated if template is copied. 15// Custom values set here. Change for a particular customer. 16var CurrencySymbol = '£'; // could be $ 17 18// Corrections for various hardware/browsers 19var P = navigator.platform; 20var bSmallAppleDevice = (P === 'iPhone' || P === 'iPad' || P === 'iPod'); 21//var bBigAppleDevice = (P === 'MacIntel' || bSmallAppleDevice); 22 23var UA = navigator.userAgent; 24// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent for details. 25var bOnSafari = (UA.indexOf('Safari/') !== -1 && UA.indexOf('Chrome/') === -1 && UA.indexOf('Chromium/') === -1); 26 27// Edge works well with a mouse, but the touch needs adjusting. 28// It's a shame we cannot distinguish between touch and non-touch on Edge. 29var bOnEdge = (UA.indexOf('Edge/') !== -1); 30 31// IE is deprecated, but lots of people still use it. So we have to make some effort to support it for now. 32// IE works well with a mouse. 33var bOnIE = (UA.indexOf('Trident/') !== -1); // Trident is the rendering engine of IE. 34 35//alert(P + ' # ' + UA); // DEBUGGING line. 36 37// #################### Define some useful functions ####################### 38 39// We have to put all functions here, as OSX does not allow functions to be inside if statements. 40 41// function to turn a slice name into a selector reference for the corresponding <section> tag 42function GetSectionTagRef(SliceName) { 43 return 'section.' + SliceName + ' '; 44} 45 46var SectionTag, SectionTags; // will be used to hold required slices 47function SectionTagExists(SliceName) { 48 if (SectionTags.hasClass(SliceName)) { 49 SectionTag = SectionTags.filter(GetSectionTagRef(SliceName)); 50 if (SectionTag.length !== 0) { // at least one slice exists, great. You could have more than one in theory. 51 return true; 52 } 53 } 54 SectionTag = undefined; // remove all data. 55 return false; 56} 57 58function GetRefItem(SectionTag, Ref) { 59 if (typeof Ref === "string") { 60 if (Ref === '') { // allows us to return the section tag itself. 61 return SectionTag; 62 } else { 63 return SectionTag.find(Ref); 64 } 65 } else { 66 return Ref; 67 } 68} 69 70// A function to easily set JQuery toggles. 71// SectionTag is a $ variable. 72function ApplyToggleVisibilityOnClick(SectionTag, ClickRef, ToggleRef, iDelay, bShowToggleItemInitially) { 73 74 var ClickItem = GetRefItem(SectionTag, ClickRef); 75 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 76 77 if (bShowToggleItemInitially) { 78 ToggleItem.show(0); 79 } else { 80 ToggleItem.hide(0); 81 } 82 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 83 // variable scoping correctly works. 84 ClickItem.click(function () { 85 ToggleItem.toggle(iDelay); 86 }); 87} 88 89function ApplyHideOnClick(SectionTag, ClickRef, ToHideRef) { 90 91 var ClickItem = GetRefItem(SectionTag, ClickRef); 92 var ToHideItem = GetRefItem(SectionTag, ToHideRef); 93 94 ClickItem.click(function () { 95 ToHideItem.hide(0); 96 }); 97} 98 99function ApplyToggleClassOnClick(SectionTag, ClickRef, ToggleRef, ClassName) { 100 101 var ClickItem = GetRefItem(SectionTag, ClickRef); 102 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 103 104 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 105 // variable scoping correctly works. 106 ClickItem.click(function () { 107 ToggleItem.toggleClass(ClassName); 108 }); 109} 110 111// function to test if text exists. 112var sAttrText, sAttrText2, sAttrText3, sAttrText4; // Results come back in these variables. 113var DollarTextarea = $("<textarea/>"); // store this once. 114function TextExists(attrText, bSplit) { 115 116 if (attrText === undefined) {return false;} 117 if (attrText === null) {return false;} 118 119 var TextToProcess = attrText.trim(); 120 if (TextToProcess === '') {return false;} 121 122 // decode the text, so that &lt; becomes < etc. 123 // This works by turning into HTML and then turning back into text. 124 if (TextToProcess.indexOf('&') !== -1) { // we could use the .includes('&') method, but it is quite new, so some browsers can't cope. 125 TextToProcess = DollarTextarea.html(TextToProcess).text(); 126 } 127 if (TextToProcess === '') {return false;} 128 129 sAttrText = ''; // set return values to blank. 130 sAttrText2 = ''; 131 sAttrText3 = ''; 132 sAttrText4 = ''; 133 if (bSplit) { 134 var arrSplitText = TextToProcess.split('*'); 135 sAttrText = arrSplitText[0].trim(); 136 if (arrSplitText.length > 1) {sAttrText2 = arrSplitText[1].trim();} 137 if (arrSplitText.length > 2) {sAttrText3 = arrSplitText[2].trim();} 138 if (arrSplitText.length > 3) {sAttrText4 = arrSplitText[3].trim();} 139 } else { 140 sAttrText = TextToProcess; 141 } 142 143 return (sAttrText + sAttrText2 + sAttrText3 + sAttrText4 !== ''); 144} 145 146// define a function, so we can activate a SlickNav menu in a controlled way. 147var IEDy = 0, bEDopen = false; 148function ActivateMenu(SliceName) { 149 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 150 151 var SectionTagRef = GetSectionTagRef(SliceName); 152 var RootMenuDeskTop = SectionTag.children('div.nav-menu').children('ul.root_menu'); 153 154 RootMenuDeskTop.slicknav({ // activate SlickNav for this slice. 155 prependTo: SectionTagRef + '> div.SlickNav_Wrapper', 156 allowParentLinks: true, // Top level items can be links 157 label: '', 158 duration:100, 159 easingOpen:'linear', 160 easingClose:'linear', 161 // Use hex escape characters here. 162 closedSymbol: '', // a logical OR "V" symbol 163 openedSymbol: '', // a nice up pointing ">" symbol 164 duplicate: true//bDesktopScreenPossible // only need to duplicate if the desktop menus are needed. 165 }); 166 167 var SlickNavLastItem = SectionTag.find('ul.slicknav_nav > li:last-child'); 168 //Add extra links onto the SlickNav menu manually, to replace top-link log-out buttons etc. 169 var ExtraLink_1 = '<li class="ExtraLink Giving">
169<a class="top-link button Login" href="/Groups/374913/GivingHomeMission.aspx">GIVING<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/LogoCircleArrow.png"></a></li>'; 170 var ExtraLink_2 = '<li class="ExtraLink ContactUs"><a class="top-link button Login ContactUs" href="/Groups/220185/Contact_Us.aspx">CONTACT US</a></li>'; 171 var ExtraLink_3 = '<li class="ExtraLink SearchOpen"></li>'; 172 $(ExtraLink_2 + ExtraLink_1 + ExtraLink_3).insertAfter(SlickNavLastItem); 173 174 if (0 && bOnTouchDevice && bDesktopScreenPossible) { // have to do more work on menus. 175 176 // Having made the SlickNav menu - delete what we don't want. 177 178 SectionTag.children("div.SlickNav_Wrapper").children("div.slicknav_menu").children('ul.slicknav_nav').find('li.SlickNavNotNeeded').remove(); 179 180 // deactivate the top level <a> tag in the desk-top version so touch-screens work correctly. 181 // The link goes nowhere, but retains all the styling. 182 RootMenuDeskTop.children("li.has_sub_menu").children('a').removeAttr("href"); 183 } 184 185 // Add a close menu icon into slickNav. 186 var SlickNavIcon = SectionTag.find('span.slicknav_icon'); 187 $('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon); 188 189 // apply all the visibility on-clicks to make the menu slice work. 190 191 // Find some commonly used items. 192 //var SearchOverlay = SectionTag.find("div.search-overlay"); 193 var SlickNavBtn = SectionTag.find("a.slicknav_btn"); 194 var Mask = BodyTag.find('div.MobileMenuMask'); 195 196 //ApplyToggleVisibilityOnClick(SectionTag, "li.ExtraLink.SearchOpen", SearchOverlay, 0, false); 197 //ApplyToggleVisibilityOnClick(SectionTag, "div.top-link-wrapper a:last-child", SearchOverlay, 0, false); 198 //ApplyHideOnClick(SectionTag, "img.search-close", SearchOverlay); 199 //ApplyHideOnClick(undefined, SlickNavBtn, SearchOverlay); 200 // Toggles for menu-bars and menu-close icons 201 ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle. 202 ApplyToggleVisibilityOnClick(SectionTag, SlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle. 203 ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, Mask, 0, false); // no delay on the toggle. 204 ApplyToggleClassOnClick(SectionTag, SlickNavBtn, '', 'SlickNavFullWidth'); 205 SlickNavBtn.click(function(){ 206 if(!bEDopen){ 207 IEDy = window.pageYOffset; 208 window.scrollTo(0,0); 209 } else { 210 window.scrollTo(0,IEDy); 211 } 212 bEDopen = !bEDopen; 213 }); 214 // Link white-eye-glass to hidden search button. 215 //var HiddenSearchBox = SearchOverlay.find('input.button'); 216 //SearchOverlay.find('img.search-EyeGlass').click(function(){HiddenSearchBox.click();}); // set up the click. 217 218 // Need autocomplete="off" to be added to the search box <input> tag. 219 // This stops horrible browser autocomplete text from appearing. 220 //SearchOverlay.find('input.text').attr("autocomplete","off"); 221 222 } 223} 224 225 226// Remove the Discount column, if it is all zeros. 227function RemoveDiscountColumnIfAllZeros(sTableFind, sTdFind) { 228 var Table = SectionTag.find(sTableFind); 229 if (Table.length === 1) { 230 var TdsToSearch = Table.find(sTdFind); 231 var bFoundDiscountColumn = false, bHideDiscountColumn = true; 232 TdsToSearch.each(function() { 233 var tdText = $(this).text().trim(); 234 if (tdText === 'Discount') { 235 bFoundDiscountColumn = true; 236 } else if (tdText !== CurrencySymbol + '0.00') { 237 bHideDiscountColumn = false; 238 } 239 }); 240 if (bFoundDiscountColumn && bHideDiscountColumn) { 241 TdsToSearch.hide(); 242 } 243 244 var bBasketTable = (sTableFind === 'table.gridstyle'); 245 246 // Remove the .00 off of prices, and any commas, to save space. 247 if (window.innerWidth < iSmWidth) { 248 Table.find('tr:not(:first-child) td:not(:first-child)').each(function() { // have to search sub-tables too with this query string. 249 var Td = $(this); 250 var tdText = Td.text().trim(); 251 if (tdText.length >= 5) { // '£0.00' is 5 chars, so look for at least this length, to avoid 0 length strings etc. 252 if (tdText.substr(0, 1) === CurrencySymbol || tdText.substr(0, 8) === ' ' + CurrencySymbol) { 253 var bUpdateText = false; 254 if (tdText.indexOf(',') !== -1) { 255 tdText = tdText.replace(',', '');
256 bUpdateText = true; 257 } 258 if (tdText.indexOf('.00') !== -1) { 259 tdText = tdText.replace('.00', ''); 260 bUpdateText = true; 261 } 262 // if (tdText.substr(-3) === '.00') { 263 // tdText = tdText.substr(0, tdText.length - 3); 264 // bUpdateText = true; 265 // } 266 if (bUpdateText) { 267 Td.text(tdText); 268 } 269 } 270 } 271 }); 272 } 273 274 if (!bBasketTable) { 275 Table.find('> tbody > tr:not(:first-child):not(:last-child):not(:nth-last-child(2)) td:first-child').each(function() { 276 var Td = $(this); 277 var tdText = Td.text().trim(); 278 if (tdText.indexOf('(by ') !== -1) { 279 Td.text(tdText.replace('(by ',' (by ')); // add the missing space before the bracket here. 280 } 281 }); 282 } else { 283 Table.find('input[type="text"]').attr('autocomplete','off'); // none of this on qty and price boxes. 284 } 285 } 286} 287 288// We use this to re-structure the Delivery and Credit Card tables. 289function MakeTableIntoOneColumn(sTableFind, bAdjustSelectOptionText) { 290 var Table = SectionTag.find(sTableFind); 291 var TableTr = Table.find('> tbody > tr'); 292 if (TableTr.length === 1) { // should be only 1 tr. 293 294 var Td2 = TableTr.children('td:last-child'); 295 $('<tr></tr>').insertAfter(TableTr); 296 var Tr2 = TableTr.next(); 297 Td2.appendTo(Tr2); 298 299 // While we are here, remove the .00 of prices in the delivery ddl, and the brackets around the price. 300 if (bAdjustSelectOptionText && window.innerWidth < iSmWidth) { 301 Table.find('select[id*="_ddlDelivery_"] option').each(function() { 302 var Option = $(this); 303 var optionText = Option.text().trim(); 304 if (optionText.length >= 7) { // '(£0.00)' is 7 chars, so look for at least this length, to avoid 0 length strings etc. 305 if (optionText.substr(-4) === '.00)') { 306 optionText = optionText.substr(0, optionText.length - 4) + ')'; // put the bracket back on for now. 307 } 308 optionText = optionText.replace(' (' + CurrencySymbol, ' ' + CurrencySymbol); 309 Option.text(optionText.substr(0, optionText.length - 1)); 310 } 311 }); 312 } 313 314 Table.show().css('visibility','visible'); // now show the table, as it was hidden in CSS. 315 } 316} 317 318function FixHotPicksModule() { 319 if (SectionTagExists('slice_ShopHotPicks')) { // check if slice exists, and load into SectionTag if it does 320 var Imgs = SectionTag.find('img[width]'); 321 if (Imgs.length !== 0) { 322 Imgs.each(function() { 323 var Img = $(this); 324 var src = Img.attr('src'); 325 var T = src; 326 src = src.replace('/Publisher/GetResizedImage.aspx?size=THUMBNAIL&url=',''); 327 if (src !== T) { 328 Img.attr('src',src); 329 } 330 }); 331 } else { // No hotpicks with images, so hide everything. 332 SectionTag.hide(); 333 } 334 } 335} 336 337function ActivateBlockImages(SliceName) { 338 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 339 SectionTag.find("div.image_blocks img" ).each(function() { 340 if (TextExists($(this).attr('alt'), true)) { // check if there is any alt text. 341 if(sAttrText3 === ''){sAttrText3 = 'View category';} 342 var cardGridCaption = '<div class="image_block_title_wrapper"><div class="image_block_title">' + sAttrText + '</div><div class="image_block_text">' + sAttrText2 + '</div><div class="image_block_textB">' + sAttrText3 + '</div></div>'; 343 if(sAttrText4 !== ''){ 344 cardGridCaption = cardGridCaption.replace('<div class="image_block_title"','<div class="image_block_title" style="color:' + sAttrText4 + ';"'); 345 cardGridCaption = cardGridCaption.replace('<div class="image_block_text"','<div class="image_block_text" style="color:' + sAttrText4 + ';"'); 346 } 347 $(cardGridCaption).insertAfter( this ); 348 } 349 $(this).removeAttr('title'); // remove the title attribute so that pop-up text does not appear. 350 }); 351 } 352} 353 354var LogoBannerSlides, LogoGalleryUL, LogoBxSlider, iLastNumLogos = -1; 355function AjdustBxSliderOnWindowResize(bFirstTimeCall) { 356 if (bSliderActive) { 357 358 var iMarginWidth = 40; 359 var iLogoMaxAllowedWidth = 180 + iMarginWidth; 360 361 var iBxWidth = LogoBannerSlides.outerWidth();
362 var iNumOfLogosVisible = Math.ceil((iBxWidth + iMarginWidth - 0.001) / iLogoMaxAllowedWidth); // account for rounding errors. 363 364 if (iNumOfLogosVisible !== iLastNumLogos) { // only do anything if we need to change the number of visible images. 365 iLastNumLogos = iNumOfLogosVisible; 366 367 var NewLogoWidth = (iBxWidth - (iNumOfLogosVisible - 1) * iMarginWidth) / iNumOfLogosVisible; 368 369 var BxValues = { 370 mode: 'horizontal', 371 auto: false, 372 pause: 5000, 373 speed: 500, 374 pager: false, 375 controls: true, 376 preloadImages: 'all', 377 touchEnabled: false, 378 minSlides: iNumOfLogosVisible, // Carousel options. 379 maxSlides: iNumOfLogosVisible, 380 moveSlides: 1, 381 slideWidth: NewLogoWidth, // (1090 - 6*20) / 7 (slide controls are outside 1170px width.) 382 slideMargin: iMarginWidth, 383 randomStart: true 384 }; 385 386 if (bFirstTimeCall) { 387 LogoBxSlider = LogoGalleryUL.bxSlider(BxValues); 388 } else { 389 LogoBxSlider.reloadSlider(BxValues); // reload rather than start again. 390 } 391 } 392 } 393} 394 395var bSliderActive = false; 396function ActivateBxSlider(SliceName) { 397 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 398 399 var HotPicks = SectionTag.next(); 400 if(HotPicks.hasClass('HiddenHotpicks') && HotPicks.children().length > 0){ 401 402 var UL = SectionTag.find('ul.gallery_ul'); 403 HotPicks.find('img[style]').each(function(){ // only get images with a [style] set. 404 var ThisImg = $(this); 405 var SRC = ThisImg.attr('src').replace('/Publisher/GetResizedImage.aspx?size=THUMBNAIL&url=',''); 406 var P = ThisImg.parent(); 407 var ItemLink = P.attr('href'); 408 var Bs = P.parent().next().find('b'); 409 var HTMLa = '<img src="' + SRC + '">'; 410 var HTMLb = '<div class="HoptPickTitle">' + Bs.eq(0).text().trim() + '</div>'; 411 var HTMLc = '<div class="HoptPickPrice">Price: <b>' + Bs.eq(1).text().trim() + '</b></div>'; 412 var HTMLd = '<a href="' + ItemLink + '">More Details</a>'; 413 var S = '<li class="gallery_li">' + HTMLa + HTMLb + HTMLc + HTMLd + '</li>'; 414 $(S).appendTo(UL); 415 }); 416 417 bSliderActive = true; 418 // ul.gallery_ul must be displayed before bx-slider can be applied. 419 // So since we hide it while the page was loading, we show it now. 420 var bannerSlides = SectionTag.find('div.bannerSlides'); // use a "find" here, as structure of slices varies. 421 bannerSlides.show(0); 422 LogoBannerSlides = bannerSlides; // get a handle. 423 var gallery_ul = bannerSlides.children('ul.gallery_ul'); 424 LogoGalleryUL = gallery_ul; 425 AjdustBxSliderOnWindowResize(true); 426 } 427 } 428} 429 430// Deal with screen resizes. This is NOT a polling routine. 431function RunOnScreenResize(){ 432 AjdustBxSliderOnWindowResize(false); // change the number of logos to show. Does not change heights. 433} 434 435// ########################## Check various conditions ############################# 436 437var bOnTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); 438 439var iDeskTopWidth = 992; 440var iMobileScreenAllowence = 64; // Because of other stuff on a screen, you have to assume the browser window could get bigger on a rotation. 441var iScreenWidthToCheck = screen.width + iMobileScreenAllowence; 442var iScreenHeightToCheck = screen.height + iMobileScreenAllowence; 443var bDesktopScreenPossible = (iScreenWidthToCheck >= iDeskTopWidth) || (iScreenHeightToCheck >= iDeskTopWidth); 444 445var iSmWidth = 768; 446 447var BodyTag = $('body'); 448if(bOnIE){BodyTag.addClass('bOnIE');} 449var bOnSystemPopupPage = BodyTag.hasClass('system_popup'); // T&C's page is one of these. 450var bUserLoggedIn = BodyTag.hasClass('logged_in_user'); 451var bOnShopPage = !bOnSystemPopupPage; 452 453SectionTags = BodyTag.find('section'); // Store all the section tags to speed up later code. 454var bOnLandingPage = SectionTags.hasClass('slice_SlideShowLogos'); 455 456// ####################################### 457// # Menu data changes 458// ####################################### 459 460// We make the required adjustments to the one set of menu HTML on the page, before cloning it and activating all the copies. 461 462var ulModuleRootMenu = BodyTag.find('ul.root_menu'); 463var bMenuPresent = (ulModuleRootMenu.length !== 0); 464if (bMenuPresent) { 465 466 // Set up the search icon in the search box. 467 if(bDesktopScreenPossible){ 468 var DeskTopSearchBox = BodyTag.find('header div.top-link-wrapper div.search-form'); 469 var HiddenSearchBox = DeskTopSearchBox.find('input.button'); 470 DeskTopSearchBox.find('input.text').attr("autocomplete","off"); 471 $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">
471').appendTo(DeskTopSearchBox); 472 DeskTopSearchBox.find('img').click(function(){HiddenSearchBox.click();}); // set up the click. 473 } 474 475 // Only keep some of the top-level menu items. 476 ulModuleRootMenu.find('li.menu_item_level_1').each(function() { 477 var ThisLi = $(this); 478 var Ahref = ThisLi.children('a').attr('href'); 479 if ( 480 !Ahref.startsWith('/Groups/213223/') && 481 !Ahref.startsWith('/Groups/220180/') && 482 !Ahref.startsWith('/Groups/220181/') && 483 !Ahref.startsWith('/Groups/220184/') && 484 !Ahref.startsWith('/Groups/220182/') && // Latest Updates 485 !Ahref.startsWith('/Shop/') && 486 !Ahref.startsWith('/Hubb?') 487 ) { 488 ThisLi.hide(); 489 } 490 }); 491 492 /* remove sub menus from Home */ 493 // This assumes that the home menu is the first item with a sub menu. 494 var HomeMenuLi = ulModuleRootMenu.children('li:first-child'); 495 HomeMenuLi.children('ul').remove(); 496 HomeMenuLi.removeClass('has_sub_menu'); // remove class 497 //HomeMenuLi.children('a').attr("href","/"); // replace link with base domain reference, not a group reference. 498 499 // remove copies of 1st item elements in dropdown sub-menu. 500 ulModuleRootMenu.find('li.menu_item_level_2:first-child').each(function() { 501 502 var ThisLi = $(this); 503 if(ThisLi.children("a[href^='/MyArea/']").length === 0) { // only if not a link into /MyArea/... 504 505 if(ThisLi.siblings().length === 0) { // no other <li> so it is the only entry 506 var ul = ThisLi.parent(); 507 ul.parent().removeClass('has_sub_menu'); // remove class from the <li> at the level above 508 ul.remove(); // delete whole parent <ul> 509 510 } else { 511 if (bOnTouchDevice && bDesktopScreenPossible) { 512 // On a touch device, the copies of the level one links at the 2nd level have to be kept for the desktop menus. 513 // But in the SlickNav menus, these 2nd level links are not needed. 514 // So we mark the items so we can delete them later, after data is copied into the SlickNav menu. 515 ThisLi.addClass('SlickNavNotNeeded'); // Mark the 2nd level <li> tag. 516 } else { 517 // Not on a touch screen, so Desktop and SlickNav menus will be the structurally the same. 518 ThisLi.remove(); // so just remove this <li> tag 519 } 520 } 521 } 522 }); 523 524 // ####################################### 525 // # SlickNav menus V1.0.10 526 // ####################################### 527 528 ActivateMenu('slice_Header_L'); 529 530 // Set up Search box inside SlickNav 531 var DeskTopSearchBoxM = BodyTag.find('header div.SlickNav_Wrapper div.search-overlay'); 532 var LIs = BodyTag.find('header div.SlickNav_Wrapper ul.slicknav_nav li.ExtraLink.SearchOpen'); 533 DeskTopSearchBoxM.appendTo(LIs); 534 var HiddenSearchBoxM = DeskTopSearchBoxM.find('input.button'); 535 DeskTopSearchBoxM.find('input.text').attr("autocomplete","off"); 536 $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">').appendTo(DeskTopSearchBoxM); 537 DeskTopSearchBoxM.find('img').click(function(){HiddenSearchBoxM.click();}); // set up the click. 538 539} // end of if bNeedMenus 540 541// Here do things ONLY needed on a home page. 542var ShopSlickNavBtn; 543if (bOnShopPage) { 544 545 var bInShopCheckout = false; 546 if (SectionTagExists('slice_ShopCheckOut')) { // check if slice exists, and load into SectionTag if it does. 547 548 if (SectionTag.find('div.container > div').length === 0) { 549 SectionTag.hide(); // if check-out is empty, then hide. 550 if (SectionTagExists('slice_ShopTermsAndConditions')) { 551 SectionTag.addClass('Grey'); 552 } 553 554 } else { 555 bInShopCheckout = true; 556 557 MakeTableIntoOneColumn('table.delivery-container', false); 558 MakeTableIntoOneColumn('table.delivery-container > tbody > tr:nth-child(2) > td > table:first-of-type', true); // has delivery select in it. 559 MakeTableIntoOneColumn('table#tblPaymentDetails', false); 560 561 // This is the shop checkout Basket. 562 RemoveDiscountColumnIfAllZeros('table.gridstyle[id$=_dgItems]', '> tbody > tr:not(:last-child) > td:nth-child(5)'); 563 // This is the table on the checkout confirm page. 564 RemoveDiscountColumnIfAllZeros('div#dvFullItemDetails > table > tbody > tr > td > table', '> tbody > tr:not(:last-child):not(:nth-last-child(2)) > td:nth-child(4)'); 565 566 // Change the item delete icon. 567 SectionTag.find('img[src="/Admin/Images/icons/delete.png"]').attr('src', sPath + 'IconBin.png'); 568 569 // Enable Revelation registration page CSS to run if needed. 570 var ShopLogin = SectionTag.find('div[id$="_divNewCustomer"]'); 571 if (ShopLogin.length === 1) { 572 var ReturningCustomers = SectionTag.find('div[id$="_pnlReturningCustomer"]'); 573 if (ReturningCustomers.length === 0) { // will be 0 if shop-only accounts are disabled. 574 ShopLogin.addClass('_user_registration_aspx'); 575 ShopLogin.children('table').addClass('shadedbox'); 576 } 577 } 578 579 var CartItemsInCheckoutTable = SectionTag.find('table[id$=_dgCartPageItems]'); 580 if (CartItemsInCheckoutTable.length === 1) { 581 CartItemsInCheckoutTable.find('img').each(function() { 582 var Img = $(this); 583 var src = Img.attr('src'); 584 var T = src;
585 src = src.replace('/Publisher/GetResizedImage.aspx?size=mini_thumbnail&url=',''); 586 if (src !== T) { 587 Img.attr('src',src); 588 } 589 }); 590 } 591 592 // Do these last, as we re-define SectionTag. 593 if (SectionTagExists('slice_ShopBasket')) { 594 SectionTag.hide(); // if check-out is visible, then hide shop basket, to avoid confusion. 595 } 596 if (SectionTagExists('slice_ShopFind')) { 597 SectionTag.hide(); // if check-out is visible, then hide shop find, to avoid confusion. 598 } 599 if (SectionTagExists('slice_ShopBreadCrumbs')) { 600 SectionTag.hide(); // if check-out is visible, then hide shop breadcrumbs, to avoid confusion. 601 } 602 if (SectionTagExists('slice_ShopHotPicks')) { 603 SectionTag.hide(); // if check-out is visible, then hide shop breadcrumbs, to avoid confusion. 604 } 605 } 606 } 607 608 if (SectionTagExists('slice_ShopCatNav')) { // check if slice exists, and load into SectionTag if it does 609 610 var SectionTagRef = GetSectionTagRef('slice_ShopCatNav'); 611 var ShopCatNavRootA = SectionTag.find('ul#ShopCatNavRoot'); 612 var ShopCatNavRootB; 613 var SIL = SectionTags.filter(GetSectionTagRef('slice_ShopItemList')).eq(0); // only the first such section (not eg. related items) 614 var bHasSomeItems = SIL.find('div[id]').length > 0; 615 var b = SIL.length > 0; 616 if(b){b = SIL.hasClass('CanHaveSideBar');} 617 if(b){b = bHasSomeItems;} 618 619 var bEmptySearch = false; 620 if(!bHasSomeItems){ 621 bEmptySearch = SIL.find('div.ShopModuleItemsList').text().trim() === 'Sorry, no items were found.'; 622 } 623 if(bEmptySearch){SIL.addClass('EmptySearch');} 624 625 var bNeedLeftHandMenu = bDesktopScreenPossible && b; 626 if(bNeedLeftHandMenu){ShopCatNavRootB = SectionTag.find('ul#ShopCatNavRoot').clone();} 627 628 ShopCatNavRootA.slicknav({ // activate SlickNav for this slice. 629 prependTo: SectionTagRef + ' div.SlickNavA', 630 allowParentLinks: true, // Top level items can be links 631 label: 'Shop Categories', 632 // Use hex escape characters here. 633 closedSymbol: '', // a logical OR "V" symbol 634 openedSymbol: '', // a nice up pointing ">" symbol 635 duplicate: false // never need the original. 636 }); 637 SectionTag.find('ul#ShopCatNavRoot > li:first-child > a').text('Shop Home'); 638 639 // Add a close menu icon into slickNav. 640 var SlickNavIcon = SectionTag.find('span.slicknav_icon'); 641 $('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon); 642 643 // apply all the visibility on-clicks to make the menu slice work. 644 645 // Find some commonly used items. 646 ShopSlickNavBtn = SectionTag.find("a.slicknav_btn"); 647 // Toggles for menu-bars and menu-close icons 648 ApplyToggleVisibilityOnClick(undefined, ShopSlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle. 649 ApplyToggleVisibilityOnClick(SectionTag, ShopSlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle. 650 651 // Build second version 652 if(bNeedLeftHandMenu){ 653 ShopCatNavRootB.slicknav({ // activate SlickNav for this slice. 654 prependTo: SectionTagRef + ' div.SlickNavB', 655 allowParentLinks: true, // Top level items can be links 656 label: 'Shop Categories', 657 // Use hex escape characters here. 658 closedSymbol: '', // a logical OR "V" symbol 659 openedSymbol: '', // a nice up pointing ">" symbol 660 duplicate: false // never need the original. 661 }); 662 663 } else { 664 SectionTag.find('div.SlickNav_Wrapper.SlickNavA').addClass('NoLeftBar'); 665 SectionTag.find('div.SlickNav_Wrapper.SlickNavB').hide(); 666 } 667 668 } 669 670 if (!bInShopCheckout) { 671 if (SectionTagExists('slice_ShopBasket')) { 672 673 // Fix basket display 674 var tdBasketTotal = SectionTag.find('table tr:last-child td'); 675 var tdBasketTotalB = tdBasketTotal.children('b'); // remember the <b> tag! 676 var BasketText = tdBasketTotalB.text(); 677 BasketText = BasketText.substr(BasketText.indexOf(CurrencySymbol)); 678 tdBasketTotalB.text(BasketText); 679 680 // Create the shop basket overlay 681 var BasketOverlay = SectionTag.clone().hide(); // might as well set this to be hidden. 682 BasketOverlay.insertAfter(SectionTag); 683 BasketOverlay.removeClass('slice_ShopBasket').addClass('slice_ShopBasketOverlay'); 684 BasketOverlay.find('input').attr('value','Checkout / Edit basket'); 685 $('<div id="BasketOverlayTop"><span></span><span id="CloseBasketOverlay"></span></div>').prependTo(BasketOverlay.find('div.ShopBasket')); 686 ApplyHideOnClick(BasketOverlay, 'span#CloseBasketOverlay', ''); 687 ApplyToggleVisibilityOnClick(undefined, SectionTag.find('table'), BasketOverlay, 0, false); // no delay on the toggle. 688 689 // Now fix the basket display again, to remove any Net total info. 690 tdBasketTotal.children('br').remove(); 691 tdBasketTotal.children('small').remove(); 692 } 693 694 if (SectionTagExists('slice_ShopFind')) { // check if slice exists, and load into SectionTag if it does. 695 696 var InputFind = SectionTag.find('input[id$="_tbSearch"]'); 697 InputFind.attr('placeholder','Search current shop category'); 698 699 // Code to fix the advanced search. 700 // var InputTag = SectionTag.find('input[id$="_chkSearchSubsections"]'); 701 // if (InputTag.length === 1) { 702 // var SelectLocation = SectionTag.find('select[id$="_ddlLocation"]') 703 // var InTrTag = SelectLocation.parent().parent(); 704 // var SubCatTrTag = InTrTag.next(); // next sibling. 705 // var sAttrModeValue = InTrTag.attr('mode'); 706 // var sAttrStyleValue = InTrTag.attr('style'); 707 // SubCatTrTag.attr('mode', sAttrModeValue); 708 // SubCatTrTag.attr('style', sAttrStyleValue); 709 // } 710 } 711 712 if (SectionTagExists('slice_ShopBreadCrumbs')) { // check if slice exists, and load into SectionTag if it does. 713 if (SectionTag.find('span.ShopBreadCrumbs').length === 0) { 714 SectionTag.hide(); 715 } 716 } 717 718 FixHotPicksModule(); 719 720 if (SectionTagExists('slice_ShopItemList')) { // check if slice exists, and load into SectionTag if it does. 721 722 // Change the missing image picture.
723 SectionTag.find('img[src*="/Shop/Admin/Images/noimage_"]').attr('src', sPath + 'NoImageAvailable.png'); 724 725 // Add a block wrapper around all the div[id]'s, so that the shop results page will render correctly. 726 var Divs = SectionTag.find('div.ShopModuleItemsList > div[id]'); 727 if (Divs.length !== 0) { 728 var ItemWrapper = $('<div class="ItemsWrapper isolate_element"></div>'); // need to add isolate_element to this element. 729 ItemWrapper.insertBefore(Divs.first()); 730 Divs.appendTo(ItemWrapper); 731 } 732 733 // Build the left-hand side shop-nav 734 // We use SectionTag.eq(0), as there may be multiple section.slice_ShopItemList on a page, eg 'Also bought' etc. 735 if(bDesktopScreenPossible && SectionTag.eq(0).hasClass('CanHaveSideBar')){ 736 var SlickNav = BodyTag.find('section.slice_ShopCatNav div.SlickNavB'); 737 var ItemList = SectionTag.eq(0).find('div.ItemsWrapper'); 738 ItemList.addClass('LeftSideBar'); 739 $('<section class="slice_ShopCatNav LeftSideBar"></section>').insertBefore(ItemList); 740 var LeftShopCatNav = SectionTag.eq(0).find('section.slice_ShopCatNav'); 741 SlickNav.appendTo(LeftShopCatNav); 742 SlickNav.find('ul#ShopCatNavRoot > li:first-child > a').text('Shop Home'); 743 SlickNav.find('a.slicknav_btn').click(); // open the menu. 744 SectionTag.eq(0).find('div.LeftInformation').removeClass('HideElement').appendTo(LeftShopCatNav); 745 $('<div class="LinkBlocker"></div>').prependTo(LeftShopCatNav.find('div.slicknav_menu')); 746 } 747 748 var spanSectionDescription = SectionTag.find('span[id$="_lblSectionDescriptionText"]'); 749 if (spanSectionDescription.text() === '') { 750 spanSectionDescription.hide(); 751 } 752 753 SectionTag.find('input[type="text"]').attr('autocomplete','off'); 754 755 // Change footer alphabetic links to just numbers. 756 var LastDiv = SectionTag.find('div.ShopModuleItemsList > div:last-child span.BelowTabs div.BelowTabs div:last-child'); 757 var Links = LastDiv.find('a[id*="_ctlAZNavigator_"]'); 758 if(Links.length > 0){ 759 SectionTag.next().next().children().hide(); // hide normal T&Cs section. 760 var i=1, CurrentLink=0; 761 Links.each(function(){ 762 var ThisAtag = $(this); 763 var S = i + ' '; 764 if(i > 1){S = ' ' + S;} 765 if(ThisAtag.hasClass('aspNetDisabled')){ 766 ThisAtag.addClass('CurrentPage').html(S); 767 CurrentLink = i; 768 } else { 769 ThisAtag.html(S); 770 } 771 i++; 772 }); 773 //console.log(CurrentLink + ' ' + Links.length); 774 if(CurrentLink < Links.length){ 775 var Aclone = Links.eq(CurrentLink).clone().addClass('NextPage').text('Next Page'); 776 Aclone.appendTo(LastDiv); 777 $('<i> </i>').appendTo(LastDiv); 778 } 779 $('<a class="TaC" href="javascript:OpenShopTermsAndConds();">Shop T&Cs</a>').appendTo(LastDiv); 780 } 781 } 782 783 if (SectionTagExists('slice_ShopItemDetails')) { // check if slice exists, and load into SectionTag if it does. 784 785 // Change the missing image picture. 786 SectionTag.find('img[src*="/Shop/Admin/Images/noimage_"]').attr('src', sPath + 'NoImageAvailable.png'); 787 788 var ATag = SectionTag.find('a[title="Zoom in"]'); 789 var Img = ATag.find('> img'); 790 Img.insertAfter(ATag); // move the img tag, outside the <a> tag. 791 // ATag.hide(0); // This should already be hidden in CSS. 792 793 } else if (SectionTagExists('slice_ShopMyOrders')) { // check if slice exists, and load into SectionTag if it does. 794 795 var iNumTables = SectionTag.find('table').length; 796 if (iNumTables > 1) { // we are on an order details page, not the order list page. 797 var sTableSelector = '> div > div > table:first-of-type'; // this is the table that holds 2 sub-tables. 798 if (window.innerWidth < iSmWidth) { 799 MakeTableIntoOneColumn(sTableSelector, false); 800 } else { 801 SectionTag.find(sTableSelector).show(); 802 } 803 RemoveDiscountColumnIfAllZeros('table[id$="_dgItems"]', '> tbody > tr > td:nth-child(5)'); 804 } 805 } 806 807 } 808} 809 810if (bSmallAppleDevice) { 811 // Parallex images are often a mess on small apple devices, so add a tag onto the <body> tag so we can take evasive action. 812 BodyTag.addClass('OnSmallAppleDevice'); 813} 814 815 816 if(bOnLandingPage){ 817 // Category gallery 818 ActivateBlockImages('slice_image_blocks_3'); 819 820 // Hotpicks gallery. 821 ActivateBxSlider('slice_SlideShowLogos'); 822 823 if (bSliderActive) { 824 window.addEventListener("resize", function(){RunOnScreenResize();}, false); 825 } 826 } 827 828// Sort out login/logout/register/web-office links 829if (bUserLoggedIn) { 830 var SB = BodyTag.find('div.HiddenStatusBar'); 831 if (SB.length === 1) { 832 var bWebOfficeActive = (SB.find('a.weboffice_link').length === 1); 833 if (!bWebOfficeActive) { // Need to hide WO links. 834 BodyTag.find('section.NewsLetterFooter a.FooterWebOffice').hide(); 835 } 836 } 837} 838 839// Fix the cookies slice 840var CS = BodyTag.find('footer div.slice_Cookies'); 841 if (CS.length === 1) { 842 CS.find('img').attr('src','/Images/Content/2019/Templates/54496/images/IconClose.png'); 843 } 844 845});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.