1/* ================================================== 2#Image functions 3#Recently viewed 4#Load more / infinite load 5#Filter products with AJAX 6#Search autocomplete 7#Sidebar filter on collection pages 8#Misc 9#Quick shop 10#Newsletter popup 11 12/*============================================================================ 13 Image functions 14==============================================================================*/ 15 16var usePageDots = false; 17 18var imageFunctions = { 19 zoom: function(zoomParent, enableTouch, magnify){ 20 var activateZoom = $(zoomParent).data('zoom'); 21 if (activateZoom){ 22 $(zoomParent + ' img') 23 .wrap('<span style="display:inline-block"></span>') 24 .css('display', 'block') 25 .parent() 26 .zoom({ 27 touch: enableTouch, 28 magnify: magnify ? magnify : 1 29 }); 30 } 31 }, 32 linkGalleryAndCarousel: function($gallery, $carousel){ 33 34 $carousel.find('.gallery-cell:nth-child(1)').addClass('is-nav-selected'); 35 36 //EVENT - click on carousel item to slide gallery 37 $carousel.on( 'click', '.gallery-cell', function() { 38 var index = $(this).index(); 39 $carousel.find('.is-nav-selected').removeClass('is-nav-selected'); 40 $(this).addClass('is-nav-selected'); 41 $gallery.flickity( 'select', index ); 42 }); 43 44 //EVENT - update carousel based on gallery index 45 $gallery.on( 'select.flickity', function() { 46 var galleryData = $(this).data('flickity'); 47 if (galleryData){ 48 $carousel.find('.is-nav-selected').removeClass('is-nav-selected'); 49 $carousel.find('.gallery-cell:nth-child(' + (galleryData.selectedIndex + 1) + ')').addClass('is-nav-selected'); 50 } 51 }); 52 }, 53 fullWidth: function(images, imageContainer){ 54 $(images).each(function(){ 55 var $image = $(this), 56 alt = $image.attr('alt'), 57 src = $image.attr('src'); 58 59 if (alt.indexOf("[") >= 0){ 60 61 //remove from description 62 $image.remove(); 63 64 //find shortcode values and remove from alt 65 var shortcodes = alt.match(/\[(.*?)\]/ig); 66 alt = alt.replace(/\[(.*?)\]/ig, ''); 67 68 //remove brackets from shortcode to be used as classes 69 var captionClass = $.map( shortcodes, function( value, index ) { 70 value = value.replace(/[\[\]']+/g,''); 71 return value; 72 }); 73 74 //markup for caption 75 76 var caption = [ 77 '<div class="position-' + (captionClass.length ? captionClass : 'center') + ' caption js-caption">', 78 '<div class="caption-content caption-background-false align-' + (captionClass.length ? captionClass : 'center') + '">', 79 '<p class="headline">' + alt + '</p>', 80 '</div>', 81 '</div>' 82 ].join(''); 83 84 //image attributes added 85 $image.attr({ 86 alt: alt, 87 class: 'lazyload none', 88 src: src, 89 dataSizes: 'auto' 90 }); 91 92 var image = $image.prop('outerHTML') 93 var banner = '<div class="banner">' + image + caption + '</div>' 94 95 $(imageContainer).append(banner); 96 } 97 }) 98 }, 99 showSecondaryImage: function(){ 100 if ($(window).width() > 798) { 101 $('body').on("mouseenter", ".swap-true", function() { 102 $(this).toggleClass('toggle-images'); 103 }); 104 105 $('body').on("mouseleave", ".swap-true", function() { 106 $(this).toggleClass('toggle-images'); 107 }); 108 } 109 } 110} 111 112/*============================================================================ 113 Recently viewed 114==============================================================================*/ 115 116var recentlyViewed = { 117 init: function(){ 118 119 var productHandle, 120 rvCookie, 121 rvProducts, 122 displayProducts, 123 rvProductArray; 124 125 if ($('.js-product_section[data-rv-handle]').length){ 126 productHandle = $('.js-product_section').data('rv-handle').toString(); 127 rvCookie = Cookies.get('recentlyViewed'); 128 rvProducts = recentlyViewed.getCookieProducts(rvCookie, productHandle); 129 } else if ($('.recently-viewed__section').length){ 130 rvCookie = Cookies.get('recentlyViewed'); 131 rvProducts = recentlyViewed.getCookieProducts(rvCookie, productHandle); 132 } else if ($('.js-sidebar-recently-viewed').length){ 133 rvCookie = Cookies.get('recentlyViewed'); 134 rvProducts = recentlyViewed.getCookieProducts(rvCookie, productHandle); 135 } 136 137 if (rvProducts){ 138 rvProductArray = unescape(rvProducts).split(','); 139 } 140 141 if (productHandle){ 142 143 if(!$.inArray(productHandle, rvProductArray) !== -1){ 144 displayProducts = []; 145 rvProductArray.unshift(productHandle); 146 $.each(rvProductArray, function(i, el){ 147 if($.inArray(el, displayProducts) === -1) displayProducts.push(el); 148 }); 149 } 150 151 recentlyViewed.setCookieProducts(displayProducts); 152 } else { 153 displayProducts = rvProductArray; 154 } 155 156 if ($('.recently-viewed__section').length){ 157 var parent = '.recently-viewed__section'; 158 recentlyViewed.getProductInformation(parent, displayProducts, productHandle); 159 } else if ($('.js-recently-viewed .rv-main').length){ 160 var parent = '.js-recently-viewed'; 161 recentlyViewed.getProductInformation(parent, displayProducts, productHandle); 162 } 163 164 if ($('.sidebar .js-sidebar-recently-viewed').length){ 165 var parent = '.sidebar .js-sidebar-recently-viewed'; 166 if (productHandle){ 167 recentlyViewed.getProductInformation(parent, displayProducts, productHandle); 168 } else { 169 recentlyViewed.getProductInformation(parent, displayProducts); 170 } 171 $('.js-sidebar-recently-viewed.hidden').parents('.sidebar-block').hide(); 172 } 173 174 }, 175 getCookieProducts: function(rvCookie, productHandle){ 176 177 if (!rvCookie && productHandle) { 178 Cookies.set('recentlyViewed', productHandle, { expires: 30, path: '/' }); 179 rvCookie = Cookies.get('recentlyViewed'); 180 } else { 181 rvCookie = Cookies.get('recentlyViewed'); 182 } 183 184 return rvCookie; 185 186 }, 187 setCookieProducts: function(rvProductArray){ 188 Cookies.set('recentlyViewed', escape(rvProductArray.join(',')), { expires: 30, path: '/' }); 189 }, 190 getProductInformation: function(parent, displayProducts, productHandle){ 191 192 if (productHandle){ 193 displayProducts.splice( $.inArray(productHandle, displayProducts), 1 ); 194 } 195 196 var productLimit = $(parent).data('visible-products'); 197 198 if (productLimit && displayProducts){ 199 displayProducts = displayProducts.slice(0, productLimit); 200 } 201 202 $.each(displayProducts, function (index, value) { 203 204 if (value){ 205 $(parent).removeClass('hidden'); 206 207 $(parent).parents('.sidebar-block').show(); 208 209 $.ajax({ 210 type: 'GET', 211 url: '/products/' + value + '?view=rv', 212 success: function(data) { 213 214 var rvProduct = $(data).find('.js-recently-viewed-product'); 215 216 $(parent).find(' .rv-box-' + index ).append(rvProduct); 217 218 //Convert pricing 219 220 221 }, 222 error: function(x, t, m) { 223 console.log(x); 224 console.log(t); 225 console.log(m); 226 }, 227 dataType: "html" 228 }); 229 } 230
231 if ($(parent).find('.rv-main').hasClass('js-rv-slider')){ 232 if (displayProducts.length <= productLimit) { 233 $('.js-rv-slider .gallery-cell').eq(displayProducts.length).nextAll().addBack().remove(); 234 } else { 235 $('.js-rv-slider .gallery-cell').eq(productLimit).nextAll().addBack().remove(); 236 } 237 recentlyViewed.createSlider(parent, productLimit); 238 } else if ($(parent).find('.rv-main').hasClass('js-rv-grid')){ 239 if (displayProducts.length <= productLimit) { 240 $('.js-rv-grid .thumbnail').eq(displayProducts.length).nextAll().addBack().remove(); 241 } else { 242 $('.js-rv-grid .thumbnail').eq(productLimit).nextAll().addBack().remove(); 243 } 244 } 245 }); 246 }, 247 248 createSlider: function(el, productsAvailable){ 249 250 var products_per_slide = $('.js-rv-slider').data('products-per-slide'); 251 var products_limit = $('.js-rv-slider').data('products-limit'); 252 var products_available = productsAvailable; 253 var indexProductsAvailable = productsAvailable - 1; 254 var rvProductstoShow = $('.js-rv-slider').find('.gallery-cell'); 255 var cellAlign, 256 draggable, 257 prevNext, 258 wrapAround, 259 initialIndex; 260 261 if (products_per_slide == "2" && products_available > products_per_slide && products_limit > products_per_slide || products_per_slide == "4" && products_available > products_per_slide && products_limit > products_per_slide || products_per_slide == "6" && products_available > products_per_slide && products_limit > products_per_slide){ 262 cellAlign = "left"; 263 } else { 264 cellAlign = "center"; 265 } 266 267 if (products_available > products_per_slide && products_limit > products_per_slide) { 268 draggable = true; 269 prevNext = true; 270 wrapAround = true; 271 } else { 272 draggable = false; 273 prevNext = false; 274 wrapAround = false; 275 } 276 277 if (products_per_slide == "2" && products_available > products_per_slide || products_per_slide == "4" && products_available > products_per_slide || products_per_slide == "6" && products_available > products_per_slide){ 278 initialIndex = 0; 279 } else if (products_per_slide == "3" && products_available) { 280 initialIndex = 1; 281 } else if (products_per_slide == "5" && products_available) { 282 initialIndex = 2; 283 } else if (products_per_slide == "7" && products_available) { 284 initialIndex = 3; 285 } 286 287 if ($(window).width() <= 798) { 288 289 cellAlign = "center"; 290 initialIndex = 1; 291 292 if (rvProductstoShow.length <= 2){ 293 draggable = false; 294 prevNext = false; 295 wrapAround = false; 296 } else if (products_available > 3 && products_limit > 3) { 297 draggable = true; 298 prevNext = true; 299 wrapAround = true; 300 } else { 301 draggable = false; 302 prevNext = false; 303 wrapAround = false; 304 } 305 306 $('.js-rv-slider').parents('.even-num-slides').removeClass('even-num-slides'); 307 } 308 309 $('.js-rv-slider').flickity({ 310 "lazyLoad": 2, 311 "imagesLoaded": true, 312 "draggable": draggable, 313 "prevNextButtons": prevNext, 314 "wrapAround": wrapAround, 315 "cellAlign": cellAlign, 316 "pageDots": usePageDots, 317 "contain": true, 318 "freeScroll": true, 319 "arrowShape": arrowSize, 320 "initialIndex": initialIndex 321 }); 322 323 $('.js-rv-slider').addClass('slider-initialized'); 324 } 325} 326 327/* =============================================== 328 #Load more / infinite load 329================================================== */ 330 331//Collection template 332 333var enableLoadMoreProducts = function(){ 334 $('body').on('click', '.js-load-more a', function(e){ 335 enableInfiniteScroll(); 336 e.stopPropagation(); 337 return false; 338 }); 339} 340 341var enableInfiniteScroll = function(){ 342 if ($('.collection-matrix').length) { 343 var infiniteScroll = new Waypoint.Infinite({ 344 element: $('.collection-matrix')[0], 345 items: '.collection-matrix', 346 more: '.load-more__btn', 347 loadingClass: 'loading-in-progress', 348 onBeforePageLoad: function(){ 349 $('.js-load-more').hide(); 350 }, 351 onAfterPageLoad: function(data){ 352 $('.collection-matrix > .collection-matrix .thumbnail').unwrap('.collection-matrix'); 353 354 355 } 356 }) 357 } 358} 359 360//Search template 361 362var enableLoadMoreSearch = function(){ 363 $('body').on('click', '.js-load-more a', function(e){ 364 enableInfiniteSearchScroll(); 365 e.stopPropagation(); 366 return false;
367 }); 368} 369 370var enableInfiniteSearchScroll = function(){ 371 if ($('.search-matrix').length) { 372 var infiniteSearchScroll = new Waypoint.Infinite({ 373 element: $('.search-matrix')[0], 374 items: '.search-matrix', 375 more: '.load-more__btn', 376 loadingClass: 'loading-in-progress', 377 onBeforePageLoad: function(){ 378 $('.js-load-more').hide(); 379 }, 380 onAfterPageLoad: function(data){ 381 $('.search-matrix > .search-matrix .thumbnail').unwrap('.search-matrix'); 382 383 384 } 385 }) 386 } 387} 388 389/*============================================================================ 390 Filter Products with AJAX 391==============================================================================*/ 392 393Shopify.queryParams = {}; 394if (location.search.length) { 395 for (var aKeyValue, i = 0, aCouples = location.search.substr(1).split('&'); i < aCouples.length; i++) { 396 aKeyValue = aCouples[i].split('='); 397 if (aKeyValue.length > 1) { 398 Shopify.queryParams[decodeURIComponent(aKeyValue[0])] = decodeURIComponent(aKeyValue[1]); 399 } 400 } 401} 402 403var quickFilter = { 404 init: function(){ 405 var selectedOptions = [], 406 query = '', 407 currentTags = '', 408 siteUrl = 'https://' + $.url('hostname'), 409 url1 = $.url('1') ? '/' + $.url('1') + '/' : '', 410 url2 = $.url('2') ? $.url('2') + '/' : '', 411 url3 = $.url('3'), 412 path = url1 + url2 + url3; 413 path = path.replace("undefined", ""); 414 415 if ($(window).width() < 767) { 416 if ($('#mobile-default').length){ 417 query = $('#mobile-default').val(); 418 } else { 419 query = url('?sort_by'); 420 } 421 }else{ 422 //Handle dropdowns if they exist 423 if ($('#sort-by').length){ 424 query = $('#sort-by').val(); 425 } else { 426 query = url('?sort_by'); 427 } 428 } 429 430 431 432 433 if ($('#tag_filter').length){ 434 435 if ($('#tag_filter').data('default-collection') != $('#tag_filter').val()){ 436 urlTag = $('#tag_filter').val().substr($('#tag_filter').val().lastIndexOf('/') + 1); 437 438 if (urlTag != 'all'){ 439 if ($.inArray( urlTag, selectedOptions ) > -1){ 440 //Do nothing 441 } else { 442 selectedOptions.unshift(urlTag); 443 } 444 } 445 } 446 } 447 448 //Add all checkbox values to array 449 $('[data-option-filter] input:checked').each(function (){ 450 selectedOptions.push($(this).val()); 451 }); 452 selectedOptions = $.makeArray(selectedOptions); 453 454 //Loop through tags to create string to update page url 455 $.each(selectedOptions, function(i, value){ 456 457 if (i != selectedOptions.length - 1) { 458 currentTags += selectedOptions[i] + '+'; 459 } else { 460 currentTags += selectedOptions[i]; 461 } 462 463 }); 464 465 Shopify.queryParams.sort_by = query; 466 query = '?' + $.param(Shopify.queryParams); 467 468 quickFilter.processUrl(path, currentTags, query); 469 470 }, 471 updateView: function(filterURL) { 472 473 $.ajax({ 474 type: 'GET', 475 url: filterURL, 476 beforeSend: function() { 477 $("body").addClass('fadeOut animated loading-in-progress filter-loading'); 478 Waypoint.destroyAll() 479 }, 480 success: function(data) { 481 $(".collection-matrix").removeClass('loading-in-progress'); 482 $(".collection-matrix").removeClass('filter-loading'); 483 var filteredBreadcrumb = $(data).find('.breadcrumb_text').html(); 484 $('.breadcrumb_text').html(filteredBreadcrumb); 485 486 var filteredPagination = $(data).find('.paginate').html(); 487 $('.paginate').html(filteredPagination); 488 489 var filteredSidebar = $(data).find('.sidebar').html(); 490 $('.sidebar').html(filteredSidebar); 491 492 var filteredPageLinks = $(data).find('.paginate').html(); 493 $('.paginate').empty(); 494 $('.paginate').html(filteredPageLinks); 495 496 var filteredData = $(data).find('.collection-matrix'); 497 $('.collection-matrix').remove(); 498 filteredData.insertBefore( $('.load-more__icon') ); 499 500 window.history && window.history.pushState && window.history.pushState("", "", filterURL); 501 502 if ($('.sidebar__collection-filter').length){ 503 collectionSidebarFilter.init(); 504 } 505 506 507 508 509 510 511 window.location.reload(); 512 }, 513 error: function(x, t, m) { 514 console.log(x); 515 console.log(t); 516 console.log(m); 517 location.replace(location.protocol + '//' + location.host + filterURL); 518 519 }, 520 dataType: "html" 521 }); 522 },
523 processUrl: function(path, tags, query){ 524 525 var query = query.replace(/\page=(\w+)&/, ''), 526 urlString = ''; 527 528 urlString = path + tags + query; 529 530 quickFilter.updateView(urlString); 531 532 } 533} 534 535/*============================================================================ 536 Search autocomplete 537==============================================================================*/ 538 539var searchAutocomplete = { 540 init: function(){ 541 542 var currentAjaxRequest = null; 543 var shopURL = $('body').data('shop-url'); 544 545 546 if (window.location.href.indexOf("zh-CN") > -1) { 547 var searchPath = shopURL + '/zh-CN/search?type=product&q='; 548 } 549 else{ 550 var searchPath = shopURL + '/search?type=product&q='; 551 } 552 553 554 555 //Submit wildcard searches 556 $(".search_form, .search__form, .header_search_form").on("submit", function(e){ 557 var formValue = $(this).find('input[name="q"]').val(); 558 var cleanFormValue = encodeURI(formValue); 559 560 e.preventDefault(); 561 562 if(cleanFormValue == null) { 563 window.location.href = '/search'; 564 } else { 565 //window.location.href = searchPath + cleanFormValue + '*'; 566 window.location.href = searchPath + cleanFormValue; 567 } 568 }); 569 570 var searchForms = $('form.search_form, form.search, form.header_search_form').each(function() { 571 572 var input = $(this).find('input[name="q"]'); 573 574 // Adding a list for showing search results. 575 $('<div class="search__results-wrapper"><ul class="search__results"></ul></div>').appendTo($(this)); 576 // Listening to keyup and change on the text field within these search forms. 577 input.attr('autocomplete', 'off').bind('keyup change', function() { 578 579 if(input.val() == '') { 580 $('.search__results').hide(); 581 $('.search__results').empty(); 582 } 583 584 var term = $(this).val(); 585 var cleanTerm = encodeURI(term); 586 587 var form = $(this).closest('form'); 588 var searchURL = searchPath + cleanTerm; 589 590 var resultsList = form.find('.search__results'); 591 592 if (term.length >= 3) { 593 594 if (currentAjaxRequest != null) currentAjaxRequest.abort(); 595 596 currentAjaxRequest = $.getJSON(searchURL +'*&view=json', function(data) { 597 resultsList.empty(); 598 599 // If we have no results. 600 if(data.results_count == 0) { 601 resultsList.hide(); 602 } else { 603 // If we have results. 604 $.each(data.results, function(index, item) { 605 if(index >= 5) { 606 return false; 607 } 608 609 var link = $('<a></a>').attr('href', item.url); 610 611 //Collect collection handles if product 612 if(item.object_type == 'product') { 613 614 var collectionHandles = []; 615 for(i=0; i < item.collections.length; i++) { 616 collectionHandles.push(item.collections[i].handle); 617 } 618 619 if($.inArray('coming-soon', collectionHandles) != -1) { 620 var itemPrice = "Coming Soon"; 621 } else { 622 if(item.available == true) { 623 624 if(item.raw_compare > item.raw_price ) { 625 var itemPrice = '<span class="was_price">' + item.compare + '</span> ' + item.price; 626 } else { 627 if(item.price_varies && item.price_min > 0) { 628 var itemPrice = "from" + ' ' + item.price; 629 } else if(item.price > 0 || item.raw_price > 0) { 630 var itemPrice = item.price; 631 } else { 632 var itemPrice = 'Free'; 633 } 634 } 635 } else { 636 var itemPrice = "Sold Out"; 637 } 638 } 639 640 if(item.thumbnail != 'NULL') { 641 link.append('<div class="thumbnail"><img class="lazyload none" src="' + item.thumbnail + '" /></div>'); 642 } 643 link.append('<div class="title">' + item.title + '<br><span class="item-pricing">
643'+ itemPrice +'</span></div>'); 644 645 646 } else if(item.object_type == 'article') { 647 if(item.thumbnail != 'NULL') { 648 link.append('<div class="thumbnail"><img class="lazyload none" src="' + item.thumbnail + '" /></div>'); 649 } 650 link.append('<div class="title">' + item.title + '<br><span class="item-pricing">'+ item.text_content +'</span></div>'); 651 652 } else if(item.object_type == 'page') { 653 link.append('<div class="title">' + item.title + '<br><span class="item-pricing">'+ item.text_content +'</span></div>'); 654 } 655 656 link.wrap('<li class="item-result result--' + item.object_type + '"></li>'); 657 resultsList.append(link.parent()); 658 }); 659 // The Ajax request will return at the most 5 results. 660 // If there are more than 5, let's link to the search results page. 661 if(data.results_count >= 5) { 662 resultsList.append('<li class="all-results"><span class="title see-all"><a href="' + searchURL + '*">' + "View all results" + ' (' + data.results_count + ')</a></span></li>'); 663 } 664 resultsList.fadeIn(200); 665 } 666 }) 667 } 668 }); 669 }); 670 671 // Clicking outside makes the results disappear. 672 $(document).on('click', function(e){ 673 var container = $('[data-autocomplete-true]'); 674 if (!container.is(e.target) && container.has(e.target).length === 0) { 675 $('[data-autocomplete-true]').find('.search__results-wrapper').hide(); 676 } 677 }); 678 679 $('[data-autocomplete-true] input').on('focus', function(){ 680 $('.search__results-wrapper').hide(); 681 $(this).parents('[data-autocomplete-true]').find('.search__results-wrapper').show(); 682 }); 683 }, 684 unload: function() { 685 $('body').off('focus', '[data-autocomplete-true] input'); 686 } 687} 688 689/*============================================================================ 690 Sidebar filter on collection pages 691==============================================================================*/ 692 693var collectionSidebarFilter = { 694 init: function(){ 695 696 $('.filter-active-tag input:checked').parents('.filter-active-tag').siblings('.filter-all-tags').hide(); 697 $('.toggle-all--true .toggle_list .filter-active-tag input:checked').parents('ul.toggle_list').prev().click(); 698 699 //Hide filters if types or vendors is in URL (can't be combined) 700 if ($.url(2) === 'types' || $.url(2) === 'vendors'){ 701 $('.sidebar__collection-filter').remove(); 702 } 703 704 $('.sidebar-block:empty').prev().css('border-bottom', 'none'); 705 706 }, 707 clearAllFilters: function(){ 708 $('[data-option-filter] input').attr('checked', false); 709 $('[data-option-filter] input').trigger('change'); 710 }, 711 clearSelectedFilter: function(optionFilter){ 712 optionFilter.find('[data-option-filter] input').attr('checked', false); 713 optionFilter.find('[data-option-filter] input').trigger('change'); 714 } 715} 716 717 718 719 720/*============================================================================ 721 Misc 722==============================================================================*/ 723 724 725 var arrowSize = { 726 x0: 10, 727 x1: 60, y1: 50, 728 x2: 62, y2: 40, 729 x3: 22 730 } 731 var svgArrowSizeLeft = '<svg viewBox="0 0 100 100"><path d="M 10,50 L 60,100 L 62,90 L 22,50 L 62,10 L 60,0 Z" class="arrow"></path></svg>' 732 var svgArrowSizeRight = '<svg viewBox="0 0 100 100"><path d="M 10,50 L 60,100 L 62,90 L 22,50 L 62,10 L 60,0 Z" class="arrow" transform="translate(100, 100) rotate(180) "></path></svg>' 733 734 735var utils = { 736 createAccordion: function(container, tab, content){ 737 var $container = $(container); 738 var $tab = $(container).find(tab); 739 var $content = $(container).find(content); 740 var specificTab = container + ' ' + tab; 741 742 //Check to see if need to rearrange product tabs to create accordion (backwards compatible) 743 if (container.indexOf(".accordion-tabs") >= 0){ 744 var rearrangedTabs = $.map($tab, function(v, i) { return [v, $content[i]]; }); 745 $container.empty(); 746 747 $.each(rearrangedTabs, function (index, value) { 748 $container.append(this); 749 }); 750 751 $content.removeClass('active'); 752 $container.find('.active').next().slideToggle(); 753 754 tab = container + '> a'; 755 } 756 757 $(container).children('a').each(function(i, tab) { 758 var tab = $(this); 759 var tabValue = tab.attr('href'); //get tab id 760 tab.attr('data-tab-value', tabValue); //set tab id in data attribute 761 if(!tab.hasClass('retalierID')){ 762 tab.removeAttr("href"); //remove href (to prevent url hash update) 763 } 764 }); 765 766 $(container).find(tab + '.active').next().slideToggle(); 767 $('body').on('click', specificTab, function(e){ 768 e.preventDefault(); 769 $(this).toggleClass('active'); 770 $(this).next().slideToggle(); 771 }); 772 }, 773 mobileAccordion: function(container, tab, content){ 774 $container = $(container); 775 $tab = $(container).find(tab); 776 $content = $(container).find(content); 777 778 $(tab + '.active').next().slideToggle(); 779 780 $('body').on('click', tab, function(e){ 781 e.preventDefault(); 782 $(this).toggleClass('active'); 783 $(this).next().slideToggle(); 784 }); 785 }, 786 mobileParentActiveAccordion: function(container, tab, content){ 787 $container = $(container); 788 $tab = $(container).find(tab); 789 $content = $(container).find(content); 790 791 $(tab + '.active').parent().next().slideToggle(); 792 793 $('body').on('click', tab, function(e){ 794 e.preventDefault(); 795 $(this).toggleClass('active'); 796 $(this).parent().next().slideToggle(); 797 }); 798 }, 799 initializeTabs: function(){ 800 $('ul.tabs > li > a').attr('data-no-instant', true); 801 $('body').on('click', 'ul.tabs > li > a', function(e) { 802 e.preventDefault(); 803 var contentLocation = $(this).attr('href'); 804 if(contentLocation.charAt(0)=="#") { 805 $('ul.tabs > li > a.active').removeClass('active'); 806 $(this).addClass('active'); 807 $(this).parents('ul.tabs').next().find(contentLocation).show().css({'display': 'block'}).addClass('active').siblings().hide().removeClass('active'); 808 } 809 }); 810 }, 811 pageBannerCheck: function(){ 812 //check for header banner 813 if (!$('.page_banner').length > 0 || $('.header').hasClass('header-background--solid')) { 814 $('.feature_image').removeClass('feature_image'); 815 $('.header.is-absolute').removeClass('is-absolute'); 816 //hide secondary logo 817 $('.secondary_logo--true').find('.secondary_logo').css('display', 'none'); 818 $('.secondary_logo--true').find('.primary_logo').css('display', 'block'); 819 } else { 820 $('.header').parent().addClass('feature_image'); 821 $('.header').addClass('is-absolute'); 822 //check for secondary logo 823 if ($('header.feature_image').hasClass('secondary_logo--true')){ 824 $('.secondary_logo--true').find('.secondary_logo').css('display', 'block'); 825 $('.secondary_logo--true').find('.primary_logo').css('display', 'none'); 826 } 827 } 828 829 //check for section that uses header banner on home page 830 if ($('.index-sections').children().first('.under-menu').find('.full-width--true').length) { 831 if (!$('.header').hasClass('header-background--solid')) { 832 $('.index .header').parent().addClass('feature_image'); 833 $('.index .header').addClass('is-absolute'); 834 } 835 //check for secondary logo 836 if ($('header.feature_image').hasClass('secondary_logo--true')){ 837 $('.secondary_logo--true').find('.secondary_logo').show(); 838 $('.secondary_logo--true').find('.primary_logo').hide(); 839 } 840 } else { 841 $('.index .feature_image').removeClass('feature_image'); 842 $('.index .header.is-absolute').removeClass('is-absolute'); 843 //hide secondary logo 844 if (!$('header.feature_image').hasClass('secondary_logo--true')){ 845 $('.secondary_logo--true').find('.secondary_logo').hide(); 846 $('.secondary_logo--true').find('.primary_logo').show(); 847 } 848 } 849 850 //check for section that uses header banner on the page details template 851 if ($('.detail-sections').children().first().hasClass('under-menu')) { 852 if (!$('.header').hasClass('header-background--solid')) { 853 $('[class^="page-details"] .header').parent().addClass('feature_image'); 854 $('[class^="page-details"] .header').addClass('is-absolute'); 855 } 856 857 //check for secondary logo 858 if ($('header.feature_image').hasClass('secondary_logo--true')){ 859 $('.secondary_logo--true').find('.secondary_logo').show(); 860 $('.secondary_logo--true').find('.primary_logo').hide(); 861 } 862 } else { 863 $('[class^="page-details"] .feature_image').removeClass('feature_image'); 864 $('[class^="page-details"] .header.is-absolute').removeClass('is-absolute'); 865 866 //hide secondary logo 867 if (!$('header.feature_image').hasClass('secondary_logo--true')){ 868 $('.secondary_logo--true').find('.secondary_logo').hide(); 869 $('.secondary_logo--true').find('.primary_logo').show(); 870 } 871 } 872 }, 873 resizeActionButtons: function(){ 874 $('.js-caption:visible').each(function(){ 875 var buttonWidth = 0; 876// $(this).find('.action_button').each(function(){ 877// $button = $(this); 878// if($(this).width() > buttonWidth){ 879// buttonWidth = $(this).width(); 880// } 881// }); 882// $(this).find('.action_button').width(buttonWidth); 883 }); 884 } 885} 886 887var sliderBlock = { 888 select: function(blockId, $parentSection){ 889 var $blocks = $parentSection.find('.gallery-cell'); 890 var blockIdsArray = $blocks.map(function() { 891 return String($(this).data('block-id')); 892 }); 893
894 var $slider = $parentSection.find('[data-slider-id]'); 895 var settings = { 896 slideshowTextAnimation: $slider.data('slideshow-text-animation') 897 } 898 var flkty = $slider.data('flickity'); 899 900 $slider.flickity('pausePlayer'); 901 902 for(var i = 0; i < blockIdsArray.length; i++){ 903 if(blockIdsArray[i] === blockId){ 904 var currentSlide = i; 905 if (currentSlide !== flkty.selectedIndex){ 906 $slider.flickity( 'select', parseInt(currentSlide), false, true); 907 } 908 } 909 } 910 }, 911 deselect: function($parentSection){ 912 var $slider = $parentSection.find('.flexslider').data('flexslider'); 913 if($slider) { 914 $slider.flickity('unpausePlayer'); 915 } 916 } 917} 918 919/*============================================================================ 920 Quick shop 921==============================================================================*/ 922 923var globalQuickShopProduct; 924 925var quickShop = { 926 init: function(){ 927 928 //EVENT - click on quick-shop 929 $('body').on('click', '.js-quick-shop-link', function(e){ 930 e.preventDefault(); 931 932 //Set productData object based on data attributes 933 const productData = { 934 handle: $(this).data('handle'), 935 product_id: $(this).data('id'), 936 single_variant: $(this).attr('data-single-variant'), 937 product_in_collection_url: $(this).data('url'), 938 escaped_title: $(this).data('title'), 939 details_text: $(this).data('details-text'), 940 full_description: $(this).data('full-description'), 941 regular_description: $(this).data('regular-description'), 942 image_array: quickShop.createImageObjects($(this).data('images')), 943 collection_handles: $(this).data('collection-handles').trim(',').split(','), 944 money_format: $('body').data('money-format') 945 } 946 947 //Find current product and notify forms 948 const $notifyForm = $(this).next('.js-quickshop-forms__container').find('.notify_form'); 949 const $productForm = $(this).next('.js-quickshop-forms__container').find('.product_form'); 950 951 $.fancybox.open($('.js-quick-shop'), { 952 baseClass: 'quick-shop__lightbox product-' + productData.product_id, 953 hash: false, 954 infobar : false, 955 toolbar: false, 956 loop: true, 957 smallBtn : true, 958 mobile: { 959 preventCaptionOverlap: false, 960 toolbar: true, 961 buttons: [ 962 "close" 963 ] 964 }, 965 beforeLoad: function(){ 966 quickShop.beforeOpen(productData); 967 }, 968 afterLoad: function(){ 969 quickShop.afterContent($productForm, $notifyForm, productData); 970 }, 971 beforeClose: function(){ 972 quickShop.beforeClose(productData); 973 } 974 }) 975 976 }); 977 978 }, 979 createImageObjects: function($images){ 980 //split image info 981 const image_paths_alts = $images.split('~'); 982 983 //Create new array with image objects 984 const imageArray = image_paths_alts.map(function(image){ 985 var imageInfo = image.split('^'); 986 return { 987 path: imageInfo[0], 988 alt: imageInfo[1], 989 id: imageInfo[2] 990 } 991 }); 992 993 return imageArray; 994 }, 995 beforeOpen: function(productData) { 996 997 //Add image elements before gallery is opened 998 quickShop.populateGallery(productData.image_array); 999 1000 $('.js-sale-banner, .js-sold-out, .js-current-price, .js-was-price, .js-savings, .js-new-banner, .js-pre-order-banner').empty(); 1001 $('.modal_price, .js-notify-form').show(); 1002 1003 if (productData.image_array.length > 1) { 1004 $('.js-gallery-modal').addClass('multi-image'); 1005 $('.js-gallery-modal').removeClass('single-image'); 1006 $('.js-gallery-modal').addClass('is-draggable'); 1007 } else { 1008 $('.js-gallery-modal').addClass('single-image'); 1009 $('.js-gallery-modal').removeClass('multi-image'); 1010 } 1011 1012 }, 1013 afterContent: function($productForm, $notifyForm, productData) { 1014 1015 quickShop.retrieveProductInfo(productData); 1016 1017 var prevNext = false; 1018 var draggable = false; 1019 if (productData.image_array.length > 1) { 1020 prevNext = true; 1021 draggable = true; 1022 } else { 1023 prevNext = false;
1024 draggable = false; 1025 } 1026 1027 //Add main gallery 1028 $('.js-gallery-modal').flickity({ 1029 "adaptiveHeight": true, 1030 "wrapAround": "true", 1031 "cellAlign": "left", 1032 "draggable": draggable, 1033 "contain": true, 1034 "imagesLoaded": true, 1035 "lazyLoad": 2, 1036 "pageDots": false, 1037 "dragThreshold": 10, 1038 "arrowShape": arrowSize 1039 }); 1040 1041 1042 1043 //Copy form data to modal 1044 $('.quick-shop__lightbox .js-notify-form').append($notifyForm); 1045 $('.quick-shop__lightbox .js-product-form').append($productForm); 1046 1047 //Initiate selectCallback 1048 if($productForm.hasClass("product_form_options") && $productForm.hasClass("viewed") == false) { 1049 //If form hasn't been viewed previously, run OptionSelectors function 1050 new Shopify.OptionSelectors($productForm.data("select-id"), 1051 { 1052 product: $productForm.data("product"), 1053 onVariantSelected: selectCallback, 1054 enableHistoryState: $productForm.data("enable-state") 1055 }); 1056 } else { 1057 //If form has been previously viewed, just convert currencies 1058 1059 } 1060 1061 //Link sold out options when there is more than one option available (eg. S is selected and Yellow option appears as sold out) 1062 1063 const JSONData = $productForm.data('product'); 1064 const productID = productData.section_id; 1065 const productSection = '.product-' + productID + ' .js-product_section'; 1066 const swatchOptions = $productForm.find('.swatch_options .swatch'); 1067 if (swatchOptions.length > 1){ 1068 Shopify.linkOptionSelectors(JSONData, productSection); 1069 } 1070 1071 1072 $('.js-quick-shop select[name="id"]').trigger('change'); 1073 1074 utils.initializeTabs(); 1075 1076 $('.js-quick-shop .text-modal-wrap iframe[src*=youtube], .js-quick-shop .text-modal-wrap iframe[src*=vimeo]').mediaWrapper({ 1077 intrinsic: true 1078 }); 1079 1080 productPage.productSwatches(); 1081 1082 }, 1083 beforeClose: function(productData) { 1084 1085 const $insertedNotifyForm = $('.quick-shop__lightbox .notify_form'); 1086 const $insertedProductForm = $('.quick-shop__lightbox .product_form'); 1087 1088 //Copy form data back to product loop and add .viewed 1089 $('.js-quickshop-forms--'+ productData.product_id).append($insertedProductForm); 1090 $('.js-quickshop-forms--'+ productData.product_id).append($insertedNotifyForm); 1091 $('.js-quickshop-forms--'+ productData.product_id +' .product_form').addClass('viewed'); 1092 $('.js-quickshop-forms--'+ productData.product_id +' .notify_form').addClass('viewed'); 1093 1094 //Find gallery and carousel 1095 const $gallery = $('.js-gallery-modal'); 1096 const $carousel = $('.js-gallery-carousel'); 1097 1098 $('.js-gallery-carousel .gallery-cell').off('click'); 1099 1100 //Remove image slides from gallery 1101 $gallery.flickity( 'remove', $('.gallery-cell', $gallery)); 1102 1103 //Destroy sliders when modal closes 1104 $gallery.flickity('destroy'); 1105 if ($carousel.hasClass('flickity-enabled')){ 1106 $carousel.flickity( 'remove', $('.gallery-cell', $carousel) ); 1107 $carousel.flickity('destroy'); 1108 } else { 1109 $carousel.find('.gallery-cell').remove(); 1110 } 1111 1112 const variantPrice = $('.js-current-price .money').text(); 1113 $('.js-quick-shop-link[data-id=' + productData.product_id + ']').attr('data-initial-modal-price', variantPrice); 1114 $('.js-current-price, .js-was-price, .js-savings').empty(); 1115 1116 }, 1117 retrieveProductInfo: function(productData){ 1118 $.ajax({ 1119 dataType: "json", 1120 async: false, 1121 cache: false, 1122 url: "/products/" + productData.handle + ".js", 1123 success: function(product) { 1124 //Create new object combining info 1125 product = $.extend({}, product, productData); 1126 1127 globalQuickShopProduct = product; 1128 quickShop.updateVariant(product.variants[0].id.toString(), product); 1129 1130 } 1131 }); 1132 1133 }, 1134 updateVariant: function(variant){ 1135 1136 if (globalQuickShopProduct != 'undefined'){ 1137 1138 var product = globalQuickShopProduct; 1139 1140 $('.js-current-price').html(''); 1141 $('.js-was-price').html(''); 1142 $('.js-savings').html(''); 1143 1144 //Title and Vendor 1145 $('.js-product-title').html('<a href="'+ product.product_in_collection_url +'" title="'+ product.escaped_title +'">'+ product.title +'</a>'); 1146 $('.js-product-vendor') 1147 .html('<a href="/collections/vendors?q=' + product.vendor +'">' + product.vendor + '</a>'); 1148 1149 //Product Description 1150 $('.js-full-description').html(product.full_description); 1151 $('.js-regular-description').html(product.regular_description); 1152 var productDetails = '<a href="'+ product.product_in_collection_url +'" class="secondary_button" title="'+ product.escaped_title +' Details">
1152'+ product.details_text +'</a>'; 1153 $('.js-product-details').html(productDetails); 1154 1155 //Collection banners 1156 $.each( product.collection_handles, function( value, index ) { 1157 if (this.toString() == 'new'){ 1158 $('.js-new-banner').html("New"); 1159 } 1160 if (this.toString() == 'pre-order'){ 1161 $('.js-pre-order-banner').html("Pre-Order"); 1162 } 1163 if (this.toString() == 'coming-soon'){ 1164 product.price = "Coming Soon"; 1165 } 1166 1167 }); 1168 1169 if (product.single_variant == 'true'){ 1170 1171 //No variants 1172 //Sale Banner 1173 1174 if (product.compare_at_price > product.price){ 1175 $('.js-sale-banner').html("Sale"); 1176 } 1177 1178 1179 //Sale 1180 if (product.compare_at_price > product.price) { 1181 $('.js-current-price').addClass('sale'); 1182 } else { 1183 $('.js-current-price').removeClass('sale'); 1184 } 1185 1186 //Availability 1187 if (product.available == false){ 1188 $('.js-sold-out').html("Sold Out"); 1189 } else { 1190 $('.js-sold-out').html(''); 1191 } 1192 1193 //Price 1194 if (product.available == true) { 1195 $('.js-notify-form').hide(); 1196 1197 if (product.compare_at_price > product.price) { 1198 $('.js-was-price').html('<span class="money">' + Shopify.formatMoney(product.variants[0].compare_at_price, product.money_format) + '</span>'); 1199 $('.js-savings').html("You Save" + ' ' + parseInt(((product.variants[0].compare_at_price - product.variants[0].price) * 100) / product.variants[0].compare_at_price) + '% (' + '<span class="money">' + Shopify.formatMoney(product.variants[0].compare_at_price - product.variants[0].price, product.money_format) + '</span>)'); 1200 } 1201 1202 if (product.price == "Coming Soon"){ 1203 $('.js-current-price').html("Coming Soon"); 1204 } else if (product.price) { 1205 $('.js-current-price').html('<span class="money">' + Shopify.formatMoney(product.variants[0].price, product.money_format) + '</span>'); 1206 } else { 1207 $('.js-current-price').html('Free'); 1208 } 1209 } 1210 1211 } else { 1212 1213 //Variant loop 1214 for (var i = 0; i < product.variants.length; i++) { 1215 1216 if (variant == product.variants[i].id.toString()){ 1217 //Sale Banner 1218 1219 if (product.variants[i].compare_at_price > product.variants[i].price){ 1220 $('.js-sale-banner').html("Sale"); 1221 } 1222 1223 1224 //Sale 1225 if (product.variants[i].compare_at_price > product.variants[i].price) { 1226 $('.js-current-price').addClass('sale'); 1227 } else { 1228 $('.js-current-price').removeClass('sale'); 1229 } 1230 1231 //Availability 1232 if (product.variants[i].available == false){ 1233 $('.js-sold-out').html("Sold Out"); 1234 } else { 1235 $('.js-sold-out').html(''); 1236 } 1237 1238 //Price 1239 if (product.variants[i].available == true) { 1240 $('.js-notify-form').hide(); 1241 1242 if (product.variants[i].compare_at_price > product.variants[i].price) { 1243 $('.js-was-price').html('<span class="money">' + Shopify.formatMoney(product.variants[i].compare_at_price, product.money_format) + '</span>'); 1244 $('.js-savings').html("You Save" + ' ' + parseInt(((product.variants[i].compare_at_price - product.variants[i].price) * 100) / product.variants[i].compare_at_price) + '% (' + '<span class="money">' + Shopify.formatMoney(product.variants[i].compare_at_price - product.variants[i].price, product.money_format) + '</span>)'); 1245 } 1246 1247 if (product.price == "Coming Soon"){ 1248 $('.js-current-price').html("Coming Soon"); 1249 } else if (product.variants[i].price) { 1250 $('.js-current-price').html('<span class="money">' + Shopify.formatMoney(product.variants[i].price, product.money_format) + '</span>'); 1251 } else { 1252 $('.js-current-price').html('Free'); 1253 } 1254 } else { 1255 $('.js-notify-form').show(); 1256 } 1257 } 1258 } 1259 } 1260 } 1261 1262 1263 1264 }, 1265 populateGallery: function(image_array){ 1266 1267 //Find gallery and carousel
1268 const $gallery = $('.js-gallery-modal'); 1269 const $carousel = $('.js-gallery-carousel'); 1270 1271 //Add gallery images based on product info from API 1272 function addMainGalleryImages(){ 1273 1274 $.each( image_array, function( i, image ){ 1275 1276 var imgPath = image.path; 1277 1278 var img2048x2048 = imgPath.replace(/(\.[^.]*)$/, "_2048x2048$1").replace('http:', ''); 1279 var alt = image.alt; 1280 var cellContent; 1281 1282 if (alt.indexOf("youtube") >= 0){ 1283 cellContent = '<div class="video-container youtube"><div>' + alt + '</div></div>'; 1284 } else if (alt.indexOf("vimeo") >= 0) { 1285 cellContent = '<div class="video-container vimeo"><div>' + alt + '</div></div>'; 1286 } else { 1287 cellContent = '<img src="' + img2048x2048 + '" alt="' + alt + '" data-image-id="' + image.id + '" data-index="' + i + '" />'; 1288 } 1289 1290 var $cellElems = $('<div class="gallery-cell">'+ cellContent +'</div>'); 1291 $('.js-gallery-modal').append($cellElems); 1292 }); 1293 1294 } 1295 1296 //Add carousel images based on product info from API 1297 function addCarouselGalleryImages(){ 1298 $.each( image_array, function( i, image ){ 1299 var imgPath = image.path; 1300 var carouselSizedImg = imgPath.replace(/(\.[^.]*)$/, "_grande$1").replace('http:', ''); 1301 1302 var img = '<img src="'+ carouselSizedImg + '" alt="' + escape(image.alt) + '" />'; 1303 var $carouselCellElems = $('<div class="gallery-cell">'+ img +'</div>'); 1304 $carousel.append($carouselCellElems); 1305 }); 1306 1307 imageFunctions.linkGalleryAndCarousel($gallery, $carousel); 1308 1309 1310 1311 } 1312 1313 addMainGalleryImages(); 1314 addCarouselGalleryImages(); 1315 1316 imageFunctions.zoom('.js-gallery-modal', false); 1317 1318 } 1319} 1320 1321/*============================================================================ 1322 Newsletter Popup 1323==============================================================================*/ 1324 1325var newsletter_popup = { 1326 init: function(){ 1327 var popup = Cookies.get('popup'); 1328 var cookie_enabled = true; 1329 1330 if (cookie_enabled && popup == 'open') { 1331 return false; 1332 } else { 1333 newsletter_popup.open(); 1334 } 1335 if (cookie_enabled) { 1336 Cookies.set('popup', 'open', { expires: 14 }); 1337 } 1338 }, 1339 open: function(){ 1340 if (false || $(window).width() > 798) { 1341 setTimeout( function() { 1342 $.fancybox.open($('.js-newsletter-popup'), { 1343 baseClass: 'newsletter__lightbox', 1344 hash: false, 1345 infobar : false, 1346 toolbar: false, 1347 loop: true, 1348 smallBtn : true, 1349 mobile: { 1350 preventCaptionOverlap: false, 1351 toolbar: true, 1352 buttons: [ 1353 "close" 1354 ] 1355 } 1356 }); 1357 }, 1358 0*1000); 1359 } 1360 } 1361}
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.