1(function () { 2 'use strict'; 3 4 if (!$.evo) { 5 $.evo = {}; 6 } 7 8 var EvoClass = function() {}; 9 10 EvoClass.prototype = { 11 options: { 12 captcha: {}, 13 scrollSearch: '.smoothscroll-top-search' 14 }, 15 16 constructor: EvoClass, 17 18 generateSlickSlider: function() { 19 let self = this; 20 21 const observer = new window.IntersectionObserver(entries => { 22 for (const entry of entries) { 23 if (entry.isIntersecting) { 24 let mainNode = $(entry.target); 25 mainNode.removeClass('slick-lazy'); 26 if (!mainNode.hasClass('slick-initialized')) { 27 mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto'); 28 self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts')); 29 mainNode.find('.slick-active a:first-child').attr({ 30 'tabindex': '-1' 31 }); 32 } 33 } 34 } 35 }, { 36 root: null, 37 threshold: 0.1, // set offset 0.1 means trigger if atleast 10% of element in viewport 38 }) 39 40 document.querySelectorAll('.slick-lazy').forEach(function(slickItem) { 41 observer.observe(slickItem) 42 }); 43 44 document.querySelectorAll('.slick-lazy').forEach(function(slickItem) { 45 let startX; 46 let supportsPassive = false; 47 try { 48 let opts = Object.defineProperty({}, 'passive', { 49 get: function() { 50 supportsPassive = true; 51 } 52 }); 53 window.addEventListener("testPassive", null, opts); 54 window.removeEventListener("testPassive", null, opts); 55 } catch (e) {} 56 57 slickItem.addEventListener('touchstart', function (e) { 58 startX = e.changedTouches[0].pageX; 59 60 },supportsPassive ? { passive: true } : false); 61 slickItem.addEventListener('touchmove', function (e) { 62 let mainNode = $(this); 63 if (!mainNode.hasClass('slick-initialized') 64 && Math.abs(startX - e.changedTouches[0].pageX) > 80 65 ) { 66 mainNode.removeClass('slick-lazy'); 67 mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto'); 68 self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts')); 69 let slickOptions = mainNode.slick('getSlick'); 70 if(slickOptions.slideCount > mainNode.slick('slickGetOption', 'slidesToShow')) { 71 let goTo; 72 $.each(slickOptions.originalSettings.responsive, function (key, value) { 73 if (value.breakpoint === slickOptions.activeBreakpoint 74 && value.settings.slidesToShow !== undefined 75 ) { 76 goTo = value.settings.slidesToShow; 77 } 78 }); 79 if (goTo === undefined) { 80 goTo = slickOptions.originalSettings.slidesToScroll 81 } 82 mainNode.slick('slickGoTo', goTo || 2); 83 } 84 } 85 }, supportsPassive ? { passive: true } : false); 86 }); 87 }, 88 89 initSlick: function (node, sliderType, displayCounts = '') { 90 displayCounts = displayCounts.split(','); 91 displayCounts = [ 92 parseInt(displayCounts[0]) || 2, 93 parseInt(displayCounts[1]) || 3, 94 parseInt(displayCounts[2]) || 5, 95 parseInt(displayCounts[3]) || 7, 96 ]; 97 let sliderOptions = { 98 'box-slider' : { 99 arrows: false, 100 lazyLoad: 'ondemand', 101 slidesToShow: 1, 102 slidesToScroll: 1, 103 mobileFirst: true, 104 responsive: [ 105 { 106 breakpoint: 992, 107 settings: { 108 arrows: true, 109 } 110 } 111 ] 112 }, 113 'slider-half' : { 114 arrows: false, 115 lazyLoad: 'ondemand', 116 mobileFirst: true, 117 slidesToShow: 2, 118 slidesToScroll: 2, 119 responsive: [ 120 { 121 breakpoint: 992, 122 settings: { 123 arrows: true, 124 } 125 }, 126 { 127 breakpoint: 1300, 128 settings: { 129 slidesToShow: 3, 130 slidesToScroll: 3, 131 arrows: true, 132 } 133 } 134 ] 135 }, 136 'slider-three' : { 137 arrows: false, 138 lazyLoad: 'ondemand', 139 mobileFirst: true, 140 slidesToShow: 1, 141 slidesToScroll: 1, 142 responsive: [ 143 { 144 breakpoint: 768, 145 settings: { 146 slidesToShow: 2, 147 slidesToScroll: 2, 148 } 149 }, 150 { 151 breakpoint: 992, 152 settings: { 153 arrows: true, 154 } 155 }, 156 { 157 breakpoint: 1300, 158 settings: { 159 arrows: true, 160 slidesToShow: 3, 161 slidesToScroll: 3, 162 } 163 } 164 ] 165 }, 166 'product-slider' : { 167 rows: 0, 168 arrows: false, 169 lazyLoad: 'ondemand', 170 slidesToShow: displayCounts[0] || 2, 171 slidesToScroll: displayCounts[0] || 2, 172 mobileFirst: true, 173 responsive: [ 174 { 175 breakpoint: 768, 176 settings: { 177 slidesToShow: displayCounts[1] || 3, 178 slidesToScroll: displayCounts[1] || 3 179 } 180 }, 181 { 182 breakpoint: 992, 183 settings: { 184 slidesToShow: displayCounts[2] || 5, 185 arrows: true, 186 slidesToScroll: displayCounts[2] || 5 187 } 188 }, 189 { 190 breakpoint: 1300, 191 settings: { 192 slidesToShow: displayCounts[3] || 7, 193 arrows: true, 194 slidesToScroll: displayCounts[3] || 7 195 } 196 } 197 ] 198 },
199 'news-slider' : { 200 rows: 0, 201 slidesToShow: 1, 202 slidesToScroll: 1, 203 arrows: false, 204 infinite: false, 205 lazyLoad: 'ondemand', 206 mobileFirst: true, 207 responsive: [ 208 { 209 breakpoint: 768, 210 settings: { 211 slidesToShow: 2, 212 slidesToScroll: 2, 213 } 214 }, 215 { 216 breakpoint: 992, 217 settings: { 218 slidesToShow:3, 219 slidesToScroll: 3, 220 arrows: true 221 } 222 }, 223 { 224 breakpoint: 1300, 225 settings: { 226 slidesToShow:5, 227 slidesToScroll: 5, 228 arrows: true 229 } 230 } 231 ] 232 }, 233 'freegift' : { 234 slidesToShow: 3, 235 slidesToScroll: 3, 236 arrows: false, 237 infinite: false, 238 responsive: [ 239 { 240 breakpoint: 768, 241 settings: { 242 slidesToShow: 2, 243 slidesToScroll: 2, 244 } 245 }, 246 { 247 breakpoint: 992, 248 settings: { 249 arrows: true 250 } 251 } 252 ] 253 }, 254 'gallery' : { 255 lazyLoad: 'ondemand', 256 infinite: true, 257 dots: false, 258 arrows: true, 259 speed: 500, 260 fade: true, 261 cssEase: 'linear', 262 asNavFor: '#gallery_preview', 263 responsive: [ 264 { 265 breakpoint: 992, 266 settings: { 267 dots: true 268 } 269 } 270 ] 271 }, 272 'gallery_preview' : { 273 lazyLoad: 'ondemand', 274 slidesToShow: 5, 275 slidesToScroll: 1, 276 asNavFor: '#gallery', 277 dots: false, 278 arrows: true, 279 focusOnSelect: true, 280 responsive: [ 281 { 282 breakpoint: 768, 283 settings: { 284 slidesToShow: 4, 285 slidesToScroll: 1, 286 } 287 }, 288 { 289 breakpoint: 576, 290 settings: { 291 slidesToShow: 3, 292 slidesToScroll: 1, 293 } 294 } 295 ] 296 } 297 }; 298 if ($('#content').hasClass('col-lg-9')) { 299 sliderOptions['news-slider']['slidesToShow'] = 2; 300 } 301 if (sliderType === 'gallery_preview') { 302 sliderType = 'gallery'; 303 node = $('#gallery'); 304 } 305 if (sliderType === 'gallery') { 306 $('.js-gallery-images').removeClass('d-none'); 307 $('.slick-inital-arrow').remove(); 308 $('.initial-slick-dots').remove(); 309 $('#gallery_preview').slick(sliderOptions['gallery_preview']); 310 } 311 312 return node.slick(sliderOptions[sliderType]); 313 }, 314 315 scrollStuff: function() { 316 var breakpoint = 0, 317 pos, 318 sidePanel = $('#sidepanel_left'); 319 320 if(sidePanel.length) { 321 breakpoint = sidePanel.position().top + sidePanel.hiddenDimension('height'); 322 } 323 324 pos = breakpoint - $(this).scrollTop(); 325 326 if ($(this).scrollTop() > 200 && !$('#to-top').hasClass('active')) { 327 $('#to-top').addClass('active'); 328 } else if($(this).scrollTop() < 200 && $('#to-top').hasClass('active')) { 329 $('#to-top').removeClass('active'); 330 } 331 332 if ($(window).width() > 768) { 333 var $document = $(document), 334 $element = $('.navbar-fixed-top'), 335 className = 'nav-closed'; 336 337 $document.scroll(function() { 338 $element.toggleClass(className, $document.scrollTop() >= 150); 339 }); 340 341 } 342 }, 343 344 productTabsPriceFlow: function() { 345 var dateFormat = 'DD.MM.YYYY'; 346 if ($('html').attr('lang') !== 'de') { 347 dateFormat = 'MM/DD/YYYY'; 348 } 349 var chartOptions = { 350 responsive: true, 351 scaleBeginAtZero: false, 352 aspectRatio:3, 353 tooltips: { 354 callbacks: { 355 label: function (tooltipItem, data) { 356 var label = window.chartDataTooltip; 357 label += Math.round(tooltipItem.yLabel * 100) / 100; 358 label += ' '+window.chartDataCurrency; 359 return label; 360 } 361 } 362 }, 363 scales: { 364 xAxes: [{ 365 type: 'time', 366 time: { 367 parser: 'DD.MM.YYYY', 368 // round: 'day' 369 tooltipFormat: dateFormat 370 }, 371 display: false 372 }], 373 } 374 }; 375 var initPriceChartFunction = function() { 376 if (typeof window.priceHistoryChart !== 'undefined' && window.priceHistoryChart === null) { 377 window.priceHistoryChart = new Chart(window.ctx, { 378 type: 'line', 379 data: window.chartData, 380 options: chartOptions 381 }); 382 } 383 }; 384 initPriceChartFunction(); 385 $(document).on('priceChartUpdated', initPriceChartFunction); 386 }, 387 388 tooltips: function() { 389 $('[data-toggle="tooltip"]').tooltip(); 390 }, 391 392 bootlint: function() { 393 (function(){ 394 var p = window.alert; 395 var s = document.createElement("script"); 396 window.alert = function() { 397 console.info(arguments); 398 }; 399 s.onload = function() { 400 bootlint.showLintReportForCurrentDocument([]); 401 window.alert = p; 402 }; 403 s.src = "https://maxcdn.bootstrapcdn.com/bootlint/latest/bootlint.min.js"; 404 document.body.appendChild(s); 405 })(); 406 }, 407 408 showNotify: function(options) { 409 eModal.alert({ 410 size: 'xl',
411 buttons: false, 412 title: options.title, 413 message: options.text, 414 keyboard: true, 415 tabindex: -1}) 416 .then( 417 function() { 418 $.evo.generateSlickSlider(); 419 $(document).trigger('notification-modal-shown.et'); 420 } 421 ); 422 }, 423 424 popupDep: function() { 425 $('#main-wrapper').on('click', '.popup-dep', function(e) { 426 var id = '#popup' + $(this).attr('id'), 427 title = $(this).attr('title'), 428 html = $(id).html(); 429 eModal.alert({ 430 message: html, 431 title: title, 432 keyboard: true, 433 buttons: false, 434 tabindex: -1}) 435 .then( 436 function () { 437 //the modal just copies all the html. so we got duplicate IDs which confuses recaptcha 438 var recaptcha = $('.tmp-modal-content .g-recaptcha'); 439 if (recaptcha.length === 1) { 440 var siteKey = recaptcha.data('sitekey'), 441 newRecaptcha = $('<div />'); 442 if (typeof siteKey !== 'undefined') { 443 //create empty recapcha div, give it a unique id and delete the old one 444 newRecaptcha.attr('id', 'popup-recaptcha').addClass('g-recaptcha form-group'); 445 recaptcha.replaceWith(newRecaptcha); 446 grecaptcha.render('popup-recaptcha', { 447 'sitekey' : siteKey, 448 'callback' : 'captcha_filled' 449 450 }); 451 } 452 } 453 addValidationListener(); 454 $('.g-recaptcha-response').attr('required', true); 455 } 456 ); 457 return false; 458 }); 459 }, 460 461 popover: function() { 462 /* 463 * <a data-toggle="popover" data-ref="#popover-content123">Click me</a> 464 * <div id="popover-content123" class="popover">content here</div> 465 */ 466 $('[data-toggle="popover"]').popover({ 467 html: true, 468 sanitize: false, 469 content: function() { 470 var ref = $(this).attr('data-ref'); 471 return $(ref).html(); 472 } 473 }); 474 }, 475 476 smoothScrollToAnchor: function(href, pushToHistory) { 477 var anchorRegex = /^#[\w\-]+$/; 478 if (!anchorRegex.test(href)) { 479 return false; 480 } 481 482 var target, targetOffset; 483 target = $('#' + href.slice(1)); 484 485 if (target.length > 0) { 486 // scroll below the static megamenu 487 // JTL logic 488 // var nav = $('#jtl-nav-wrapper.sticky-top'); 489 // var fixedOffset = nav.length > 0 ? nav.outerHeight() : 0; 490 // ET Logic: get the offset for all (possibly!) sticky elements that are above the target 491 var fixedOffset = 0; 492 $('.et-sticky:not(.et-sticky-affix)').each(function () { 493 var $this = $(this); 494 fixedOffset = fixedOffset + $this.outerHeight(true); 495 }); 496 497 targetOffset = target.offset().top - fixedOffset - parseInt(target.css('margin-top')); 498 $('html, body').animate({scrollTop: targetOffset}); 499 500 if (pushToHistory) { 501 history.pushState({}, document.title, location.pathname + href); 502 } 503 504 return true; 505 } 506 507 return false; 508 }, 509 510 smoothScroll: function() { 511 var supportHistory = (history && history.pushState) ? true : false;
512 var that = this; 513 514 this.smoothScrollToAnchor(location.hash, false); 515 $(document).delegate('a[href^="#"]', 'click', function(e) { 516 var elem = e.target; 517 if (!e.isDefaultPrevented()) { 518 // only runs if no other click event is fired 519 if (that.smoothScrollToAnchor(elem.getAttribute('href'), supportHistory)) { 520 e.preventDefault(); 521 } 522 } 523 }); 524 }, 525 526 initSkipToScroll: function() { 527 // set focus on skip-to links 528 let links = $('.btn-skip-to'); 529 var that = this; 530 531 links.on('click', function(e) { 532 let url = new URL(e.target.href); 533 let target = url.hash; 534 535 that.smoothScrollToAnchor(target, false); 536 $(target).focus(); 537 }); 538 }, 539 540 initScrollSearchEvent: function() { 541 this.destroyScrollSearchEvent(); 542 let lastScroll = 0, 543 $scrollTopSearch = $(this.options.scrollSearch); 544 if ($scrollTopSearch.length) { 545 $(document).on('scroll.search', function () { 546 let newScroll = $(this).scrollTop(); 547 if (newScroll < lastScroll) { 548 if ($(window).scrollTop() > 100) { 549 $scrollTopSearch.removeClass('d-none'); 550 } else { 551 $scrollTopSearch.addClass('d-none'); 552 } 553 } else { 554 $scrollTopSearch.addClass('d-none'); 555 } 556 lastScroll = newScroll; 557 }); 558 } 559 }, 560 561 destroyScrollSearchEvent: function() { 562 $(this.options.scrollSearch).addClass('d-none'); 563 $(document).off('scroll.search'); 564 }, 565 566 initScrollEvents: function() { 567 this.initScrollSearchEvent(); 568 569 //scroll top button 570 let toTopbuttonVisible = false, 571 $toTopbutton = $('.smoothscroll-top'), 572 toTopbuttonActiveClass = 'show'; 573 574 function scrolltoTop() { 575 $(window).scrollTop(0); 576 } 577 578 function handleVisibilityTopButton() { 579 let currentPosition = $(window).scrollTop(); 580 if (currentPosition > 800) { 581 if (!toTopbuttonVisible) { 582 $toTopbutton.addClass(toTopbuttonActiveClass); 583 toTopbuttonVisible = true; 584 } 585 } else if (toTopbuttonVisible) { 586 toTopbuttonVisible = false; 587 $toTopbutton.removeClass(toTopbuttonActiveClass) 588 } 589 } 590 591 if ($toTopbutton.length) { 592 $(window).on('scroll', handleVisibilityTopButton); 593 $toTopbutton.on('click', scrolltoTop); 594 $toTopbutton.on('keyup', (e) => { 595 if(e.key === 'Enter' || e.key === ' ') { 596 scrolltoTop(); 597 } 598 }) 599 handleVisibilityTopButton(); 600 } 601 }, 602 603 resetForParallax: function() { 604 $(window).trigger('resize').trigger('scroll'); 605 }, 606 607 addCartBtnAnimation: function() { 608 var animating = false; 609 610 initCustomization(); 611 612 function initCustomization() { 613 var addToCartBtn = $('#add-to-cart button[type="submit"]'), 614 form = $('#buy_form'); 615 //detect click on the add-to-cart button 616 form.on('submit', function(e) { 617 // ET360: Fixes a bug where the basket button is getting animated even when clicking on product action elements (which also trigger a form submit but with a different intention 618 if(document.activeElement && document.activeElement.getAttribute('name') === 'Wunschliste' 619 || document.activeElement.getAttribute('name') === 'Vergleichsliste') { 620 return true; 621 } 622 if(!animating) { 623 //animate if not already animating 624 animating = true; 625 626 addToCartBtn.addClass('is-added').find('path').eq(0).animate({ 627 //draw the check icon 628 'stroke-dashoffset':0 629 }, 300, function(){ 630 setTimeout(function(){ 631 addToCartBtn.removeClass('is-added').find('span.btn-basket-check').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){ 632 //wait for the end of the transition to reset the check icon 633 addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79'); 634 animating = false; 635 }); 636 637 if( $('.no-csstransitions').length > 0 ) { 638 // check if browser doesn't support css transitions 639 addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79'); 640 animating = false; 641 } 642 }, 600); 643 }); 644 } 645 }); 646 } 647 648 }, 649 650 checkout: function() { 651 // show only the first submit button (i.g. the button from payment plugin) 652 var $submits = $('#checkout-shipping-payment') 653 .closest('form') 654 .find('button[type="submit"]'); 655 $submits.addClass('d-none'); 656 $submits.first().removeClass('d-none'); 657 658 $('input[name="Versandart"]', '#checkout-shipping-payment').on('change', function() { 659 var id = parseInt($(this).val()); 660 var $form = $(this).closest('form'); 661 662 if (isNaN(id)) { 663 return; 664 } 665 666 $form.find('fieldset, button[type="submit"]') 667 .attr('disabled', true); 668 669 var urlInstance = null; 670 if ($form.length === 1 && $form.attr('action') !== undefined) { 671 urlInstance = new URL($form.attr('action')); 672 urlInstance.searchParams.append('kVersandart', '' + id); 673 } 674 var url = urlInstance === null 675 ? $('#jtl-io-path').data('path') + '/bestellvorgang.php?kVersandart=' + id 676 : urlInstance.href; 677 $.evo.loadContent(url, function() { 678 $.evo.checkout(); 679 }, null, true); 680 }); 681 682 $('#country').on('change', function (e) { 683 var val = $(this).find(':selected').val(); 684 685 $.evo.io().call('checkDeliveryCountry', [val], {}, function (error, data) { 686 var $shippingSwitch = $('#checkout_register_shipping_address'); 687 688 if (data.response) { 689 $shippingSwitch.removeAttr('disabled'); 690 $shippingSwitch.parent().removeClass('d-none'); 691 } else { 692 $shippingSwitch.attr('disabled', true); 693 $shippingSwitch.parent().addClass('d-none'); 694 if ($shippingSwitch.prop('checked')) { 695 $shippingSwitch.prop('checked', false); 696 $('#select_shipping_address').collapse('show'); 697 } 698 } 699 }); 700 }); 701 }, 702 703 loadContent: function(url, callback, error, animation, wrapper) { 704 var that = this; 705 var $wrapper = (typeof wrapper === 'undefined' || wrapper.length === 0) ? $('#result-wrapper') : $(wrapper); 706 var ajaxOptions = {data: 'isAjax'}; 707 if (animation) { 708 $wrapper.addClass('loading'); 709 } 710 711 that.trigger('load.evo.content', { url: url }); 712
713 $.ajax(url, ajaxOptions).done(function(html) { 714 var $data = $(html); 715 if (animation) { 716 $data.addClass('loading'); 717 } 718 $wrapper.replaceWith($data); 719 $wrapper = $data; 720 if (typeof callback === 'function') { 721 callback(); 722 } 723 }) 724 .fail(function() { 725 if (typeof error === 'function') { 726 error(); 727 } 728 }) 729 .always(function() { 730 $wrapper.removeClass('loading'); 731 that.trigger('contentLoaded'); // compatibility 732 that.trigger('loaded.evo.content', { url: url }); 733 }); 734 }, 735 736 startSpinner: function (target) { 737 target = target || $('body'); 738 if ($('.jtl-spinner').length === 0) { 739 target.append('<div class="jtl-spinner"><i class="fa fa-spinner fa-pulse"></i></div>'); 740 } 741 }, 742 743 stopSpinner: function () { 744 $('.jtl-spinner').remove(); 745 }, 746 747 trigger: function(event, args) { 748 $(document).trigger('evo:' + event, args); 749 return this; 750 }, 751 752 error: function() { 753 if (console && console.error) { 754 if (1 in arguments && arguments[1] === 'abort') { 755 console.info(arguments); 756 } else { 757 console.error(arguments); 758 } 759 } 760 }, 761 762 addInactivityCheck: function(wrapper, timeoutMS = 500, stopEnter = false) { 763 var timeoutID, 764 that = this, 765 currentBox; 766 767 setup(); 768 769 function setup() { 770 $(wrapper + ' .form-counter input, ' + wrapper + ' .choose_quantity input').on('change',resetTimer); 771 $(wrapper + ' .form-counter .btn-decrement, ' + wrapper + ' .form-counter .btn-increment') 772 .on('click keydown',resetTimer) 773 .on('touchstart',resetTimer,{passive: true}); 774 if (stopEnter) { 775 $(wrapper + ' input.quantity').on('keypress', function (e) { 776 if (e.key === 'Enter') { 777 return false; 778 } else { 779 resetTimer(e); 780 } 781 }); 782 } 783 } 784 785 function startTimer() { 786 timeoutID = window.setTimeout(goInactive, timeoutMS); 787 } 788 789 function resetTimer(e) { 790 // prevents form submit on navigating via tab-key 791 if (e.keyCode !== 9) { 792 if (wrapper === '#wl-items-form') { 793 currentBox = $(e.target).closest('.productbox-inner'); 794 } 795 if (timeoutID == undefined) { 796 startTimer(); 797 } 798 window.clearTimeout(timeoutID); 799 800 startTimer(); 801 } 802 } 803 804 function goInactive() { 805 if (wrapper === '#cart-form') { 806 $(wrapper).submit(); 807 } else if (wrapper === '#wl-items-form') { 808 that.updateWishlistItem(currentBox); 809 } 810 } 811 }, 812 813 updateWishlistItem: function($wrapper) { 814 let formID = 'wl-items-form'; 815 $.evo.extended().startSpinner($wrapper); 816 $.evo.io().call( 817 'updateWishlistItem', 818 [ 819 parseInt($('#' + formID + ' input[name="kWunschliste"]').val()), 820 $.evo.io().getFormValues(formID) 821 ], 822 $(this) , function(error, data) { 823 $.evo.extended().stopSpinner(); 824 $wrapper.removeClass('loading'); 825 }); 826 }, 827 828 fixStickyElements: function() { 829 /* This functionality is handled by the sticky plugin! 830 var sticky = '.cart-summary'; 831 var navHeight = $('#jtl-nav-wrapper').outerHeight(true); 832 navHeight = navHeight === undefined ? 0 : parseInt(navHeight + 40); 833 $(sticky).css('top', navHeight); 834 */ 835 }, 836 837 setWishlistVisibilitySwitches: function() { 838 $('.wl-visibility-switch').on('change', function () { 839 $.evo.io().call( 840 'setWishlistVisibility', 841 [$(this).data('wl-id'), $(this).is(":checked"), window.globals.jtl_token], 842 $(this), 843 function(error, data) { 844 if (error) { 845 return; 846 } 847 var $wlPrivate = $('span[data-switch-label-state="private-' + data.response.wlID + '"]'), 848 $wlPublic = $('span[data-switch-label-state="public-' + data.response.wlID + '"]'), 849 $wlURLWrapper = $('#wishlist-url-wrapper'), 850 $wlURL = $('#wishlist-url'); 851 if (data.response.state) { 852 $wlPrivate.addClass('d-none'); 853 $wlPublic.removeClass('d-none'); 854 $wlURLWrapper.removeClass('d-none'); 855 $wlURL.val($wlURL.data('static-route') + data.response.url) 856 } else { 857 $wlPrivate.removeClass('d-none'); 858 $wlPublic.addClass('d-none'); 859 $wlURLWrapper.addClass('d-none'); 860 } 861 }); 862 }); 863 }, 864 865 setDeliveryAdressDefaultSwitches: function() { 866 $('.la-default-switch').on('change', function () { 867 let input = $(this); 868 $('.la-default-switch').each(function() { 869 if (input.attr('id') !== $(this).attr('id')) { 870 $(this).prop('checked', false); 871 } else { 872 $(this).prop('checked', true); 873 } 874 }); 875 $.evo.io().call( 876 'setDeliveryaddressDefault',
877 [$(this).data('la-id'), $('.jtl_token').val()], 878 $(this), function(error, data) { 879 if (error) { 880 return; 881 } 882 if (!data.response.result) { 883 input.prop('checked', false); 884 } 885 } 886 ); 887 }); 888 }, 889 890 initEModals: function () { 891 $('.author-modal').on('click', function (e) { 892 e.preventDefault(); 893 let modalID = $(this).data('target'); 894 eModal.alert({ 895 title: $(modalID).attr('title'), 896 message: $(modalID).html(), 897 buttons: false 898 }); 899 }); 900 }, 901 902 initPriceSlider: function ($wrapper, redirect) { 903 let priceRange = $wrapper.find('[data-id="js-price-range"]').val(), 904 priceRangeID = $wrapper.find('[data-id="js-price-range-id"]').val(), 905 priceRangeMin = 0, 906 priceRangeMax = $wrapper.find('[data-id="js-price-range-max"]').val(), 907 currentPriceMin = priceRangeMin, 908 currentPriceMax = priceRangeMax, 909 $priceRangeFrom = $("#" + priceRangeID + "-from"), 910 $priceRangeTo = $("#" + priceRangeID + "-to"), 911 $priceSlider = document.getElementById(priceRangeID); 912 913 if($priceSlider === null) { 914 return; 915 } 916 917 if(typeof $priceSlider !== 'undefined' && $priceSlider.noUiSlider) { 918 return; 919 } 920 921 if (priceRange) { 922 let priceRangeMinMax = priceRange.split('_'); 923 currentPriceMin = priceRangeMinMax[0]; 924 currentPriceMax = priceRangeMinMax[1]; 925 $priceRangeFrom.val(currentPriceMin); 926 $priceRangeTo.val(currentPriceMax); 927 } 928 // NOTE: noUiSlider cannot work with identical min and max range, therefore min is always rounded down and max is always rounded up 929 noUiSlider.create($priceSlider, { 930 start: [Math.floor(parseFloat(currentPriceMin)), Math.ceil(parseFloat(currentPriceMax))], 931 connect: true, 932 range: { 933 'min': Math.floor(parseFloat(priceRangeMin)), 934 'max': Math.ceil(parseFloat(priceRangeMax)) 935 }, 936 step: 1, 937 format: { 938 to: function (value) { 939 return Math.ceil(parseFloat(value)); 940 }, 941 from: function (value) { 942 return Math.floor(parseFloat(value)); 943 } 944 }, 945 handleAttributes: [ 946 { 'aria-label': 'lower' }, 947 { 'aria-label': 'upper' }, 948 ] 949 }); 950 $priceSlider.noUiSlider.on('change', function (values, handle) { 951 setTimeout(function(){ 952 $.evo.redirectToNewPriceRange(values[0] + '_' + values[1], redirect, $wrapper); 953 },0); 954 }); 955 $priceSlider.noUiSlider.on('update', function (values, handle) { 956 $priceRangeFrom.val(values[0]); 957 $priceRangeTo.val(values[1]); 958 }); 959 $('.price-range-input').on('change', function () { 960 let prFrom = parseInt($priceRangeFrom.val()), 961 prTo = parseInt($priceRangeTo.val()); 962 $.evo.redirectToNewPriceRange( 963 (prFrom > 0 ? prFrom : priceRangeMin) + '_' + (prTo > 0 ? prTo : priceRangeMax), 964 redirect, 965 $wrapper 966 ); 967 }); 968 }, 969 970 initFilters: function (href) { 971 let $wrapper = $('.js-collapse-filter'); 972 $('#submitMobileFilters').addClass('disabled'); 973 $.evo.extended().startSpinner($wrapper); 974 975 $.ajax(href, {data: {'useMobileFilters':1}}) 976 .done(function(data) { 977 $wrapper.html(data); 978 $.evo.initPriceSlider($wrapper, false); 979 $.evo.initItemSearch('filter'); 980 }) 981 .always(function() { 982 $('#submitMobileFilters').removeClass('disabled'); 983 $.evo.extended().stopSpinner(); 984 }); 985 }, 986 987 initFilterEvents: function() { 988 let initiallized = false;
989 $('#js-filters').on('click', function() { 990 if (!initiallized) { 991 $.evo.initFilters(window.location.href); 992 initiallized = true; 993 } 994 }); 995 }, 996 997 redirectToNewPriceRange: function (priceRange, redirect, $wrapper) { 998 let currentURL = window.location.href; 999 if (!redirect) { 1000 currentURL = $wrapper.find('[data-id="js-price-range-url"]').val(); 1001 } 1002 let redirectURL = $.evo.updateURLParameter( 1003 currentURL, 1004 'pf', 1005 priceRange 1006 ); 1007 // Short-Cut for AJAX Filtering in ET360v2 1008 if(typeof window.etUpdatePriceFilterUrl === 'function') { 1009 window.etUpdatePriceFilterUrl(redirectURL); 1010 return; 1011 } 1012 1013 if (redirect) { 1014 window.location.href = redirectURL; 1015 } else { 1016 $.evo.initFilters(redirectURL); 1017 } 1018 }, 1019 1020 updateURLParameter: function (url, param, paramVal) { 1021 1022 if(typeof URL === 'undefined' || typeof URLSearchParams === 'undefined') { 1023 // IE11 fallback, does not support updating get params if a # is present 1024 let newAdditionalURL = '', 1025 tempArray = url.split('?'), 1026 baseURL = tempArray[0], 1027 additionalURL = tempArray[1], 1028 temp = ''; 1029 if (additionalURL) { 1030 tempArray = additionalURL.split('&'); 1031 for (let i = 0; i < tempArray.length; i++) { 1032 if (tempArray[i].split('=')[0] != param) { 1033 newAdditionalURL += temp + tempArray[i]; 1034 temp = '&'; 1035 } 1036 } 1037 } 1038 return baseURL + '?' + newAdditionalURL + temp + param + '=' + paramVal; 1039 } 1040 1041 let newUrl = new URL(url); 1042 newUrl.searchParams.set(param, paramVal); 1043 return newUrl.toString(); 1044 }, 1045 1046 updateReviewHelpful: function(item) { 1047 let formData = $.evo.io().getFormValues('reviews-list'); 1048 formData[item.prop('name')] = ''; 1049 formData['reviewID'] = item.data('review-id'); 1050 1051 $.evo.io().call( 1052 'updateReviewHelpful', 1053 [formData], 1054 $(this) , function(error, data) { 1055 if (error) { 1056 return; 1057 } 1058 let review = data.response.review; 1059 1060 $('[data-review-id="' + review.kBewertung + '"]').removeClass('on-list'); 1061 item.addClass('on-list'); 1062 $('[data-review-count-id="hilfreich_' + review.kBewertung + '"]').html(review.nHilfreich); 1063 $('[data-review-count-id="nichthilfreich_' + review.kBewertung + '"]').html(review.nNichtHilfreich); 1064 }); 1065 }, 1066 1067 initReviewHelpful: function() { 1068 $('.js-helpful').on('click', function (e) { 1069 e.preventDefault(); 1070 $.evo.extended().updateReviewHelpful($(this)); 1071 }); 1072 }, 1073 1074 initWishlist: function() { 1075 let wlFormID = '#wl-items-form'; 1076 if ($(wlFormID).length) { 1077 $.evo.extended().addInactivityCheck(wlFormID, 300, true); 1078 $('.js-update-wl').on('change', function () { 1079 $.evo.extended().updateWishlistItem($(this).closest('.productbox-inner')); 1080 }); 1081 // Disabled in ET for it does not seem reasonable 1082 /* 1083 $('.product-list').children().each(function() { 1084 $(this).css('height', $(this).height()); 1085 }); 1086 */ 1087 } 1088 }, 1089 1090 initPaginationEvents: function() { 1091 $('.pagination-wrapper select').on('change', function () { 1092 this.form.submit(); 1093 }); 1094 }, 1095 1096 initItemSearch: function(context) {
1097 let searchWrapper = '.' + context + '-search-wrapper', 1098 searchInput = '.' + context + '-search', 1099 itemValue = '.' + context + '-item-value', 1100 item = '.' + context + '-item', 1101 clear = '.form-clear', 1102 inputSelected = 'input-group-selected', 1103 $searchWrapper = $(searchWrapper); 1104 1105 if ($searchWrapper.length === 0) { 1106 return; 1107 } 1108 $searchWrapper.each((i, itemWrapper) => { 1109 $(itemWrapper).find(searchInput).on('input', function () { 1110 filterSearch($(itemWrapper)); 1111 $(itemWrapper).find('.collapse').collapse('show'); 1112 }).on('keydown', e => { 1113 if (e.key === 'Escape') { 1114 e.stopPropagation(); 1115 } 1116 }); 1117 }); 1118 $(searchWrapper + ' ' + clear).on('click', function() { 1119 $(this).prev().val(''); 1120 $(this).addClass('d-none'); 1121 filterSearch($(this).closest(searchWrapper)); 1122 }); 1123 $(searchInput).on('focusin', function() { 1124 $(this).closest(searchWrapper).addClass(inputSelected); 1125 }).on('focusout', function() { 1126 $(this).closest(searchWrapper).removeClass(inputSelected); 1127 }); 1128 1129 function filterSearch (itemWrapper) { 1130 let searchTerm = itemWrapper.find(searchInput).val().toLowerCase(); 1131 itemWrapper.find(itemValue).each((i, itemTMP) => { 1132 itemTMP = $(itemTMP); 1133 let text = itemTMP.text().toLowerCase(); 1134 if (text.indexOf(searchTerm) === -1) { 1135 itemTMP.closest(item).hide(); 1136 } else { 1137 itemTMP.closest(item).show(); 1138 } 1139 if (searchTerm.length === 0) { 1140 itemWrapper.find(clear).addClass('d-none'); 1141 } else { 1142 itemWrapper.find(clear).removeClass('d-none'); 1143 } 1144 }); 1145 } 1146 }, 1147 1148 initSliders: function() { 1149 let wrapper = '.js-slider-wrapper', 1150 buttonF = '.js-btn-slider-sf', 1151 buttonB = '.js-btn-slider-sb', 1152 items = '.js-slider-items'; 1153 1154 $(wrapper).each(function (e) { 1155 let $buttonF = $(this).find(buttonF), 1156 $buttonB = $(this).find(buttonB), 1157 $items = $(this).find(items); 1158 1159 $buttonF.on('click', function () { 1160 $items.animate( 1161 { scrollLeft: $items.scrollLeft() + $items.width() }, 1162 300, 1163 'swing', 1164 function () { 1165 checkButtonDisable($buttonB, $buttonF, $items); 1166 }); 1167 }); 1168 $buttonB.on('click', function () { 1169 $items.animate( 1170 { scrollLeft: $items.scrollLeft() - $items.width() }, 1171 300, 1172 'swing', 1173 function () { 1174 checkButtonDisable($buttonB, $buttonF, $items); 1175 }); 1176 }); 1177 $items.on('touchend', function (e) { 1178 checkButtonDisable($buttonB, $buttonF, $items); 1179 }); 1180 }); 1181 1182 function checkButtonDisable($buttonB, $buttonF, $items) { 1183 let currentScroll = $items.scrollLeft(); 1184 if (currentScroll <= 1) { 1185 $buttonB.prop('disabled', true); 1186 } else { 1187 $buttonB.prop('disabled', false); 1188 } 1189 if (currentScroll >= $items[0].scrollWidth - $items.width()) { 1190 $buttonF.prop('disabled', true); 1191 } else { 1192 $buttonF.prop('disabled', false); 1193 } 1194 } 1195 }, 1196 1197 initSwatchFocus: function($wrapper) { 1198 $('.swatches-image>input, .swatches-text>input', $wrapper).on('focusin', function () { 1199 $(this).parent('label').addClass('focus'); 1200 }).on('focusout', function () { 1201 $(this).parent('label').removeClass('focus'); 1202 }); 1203 }, 1204 1205 registerImageHover: function($wrapper) { 1206 $(window).on("load resize", function() { 1207 let productWrapper = $('.product-wrapper'); 1208 $.each(productWrapper, function() { 1209 // Skip if element is inside a closed collapse. 1210 let collapse = $(this).closest('.collapse'); 1211 if (collapse.length === 0 || collapse.hasClass('show')) { 1212 let boxHeight = $(this).height(); 1213 $(this).height(boxHeight); 1214 } 1215 }) 1216 }) 1217 }, 1218 1219 /** 1220 * $.evo.extended() is deprecated, please use $.evo instead 1221 */ 1222 extended: function() { 1223 return $.evo; 1224 }, 1225 1226 register: function() { 1227 this.productTabsPriceFlow(); 1228 this.generateSlickSlider(); 1229 // setTimeout(() => { 1230 // $('.nav-tabs').tabdrop(); 1231 // }, 200); 1232 this.tooltips(); 1233 this.popupDep(); 1234 this.popover(); 1235 this.addCartBtnAnimation(); 1236 this.smoothScroll(); 1237 this.checkout(); 1238 if ($('body').data('page') == 3) { 1239 this.addInactivityCheck('#cart-form',500,true); 1240 } 1241 this.fixStickyElements(); 1242 this.setWishlistVisibilitySwitches(); 1243 this.setDeliveryAdressDefaultSwitches();
1244 this.initEModals(); 1245 $.evo.article().initConfigListeners(); 1246 this.initScrollEvents(); 1247 this.initSkipToScroll(); 1248 this.initReviewHelpful(); 1249 this.initWishlist(); 1250 this.initPaginationEvents(); 1251 this.initFilterEvents(); 1252 this.initItemSearch('filter'); 1253 this.initSwatchFocus(); 1254 // NOVA-specific: this.initSliders(); 1255 // NOVA-specific: this.registerImageHover(); 1256 this.wireUpPRGLinks(); 1257 }, 1258 1259 wireUpPRGLinks: function() 1260 { 1261 for (const prgLink of document.querySelectorAll('[data-prg-href]')) { 1262 prgLink.addEventListener('click', e => { 1263 e.preventDefault(); 1264 let targetUrl = atob(prgLink.dataset.prgHref); 1265 let urlInput = document.createElement('input'); 1266 let virtualForm = document.createElement('form'); 1267 document.body.append(virtualForm); 1268 urlInput.name = 'prgTargetUrl'; 1269 urlInput.value = targetUrl; 1270 virtualForm.action = window.jtlShopBaseUrl + '/prg'; 1271 virtualForm.method = 'post'; 1272 virtualForm.append(urlInput); 1273 virtualForm.submit(); 1274 }); 1275 } 1276 } 1277 }; 1278 1279 $(document).ready(function () { 1280 $.evo.register(); 1281 }); 1282 1283 // PLUGIN DEFINITION 1284 // ================= 1285 $.evo = new EvoClass(); 1286})(jQuery); 1287 1288function g_recaptcha_callback() { 1289 $.evo.renderCaptcha(); 1290}
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.