1(function($, document, window, viewport){ 2 'use strict'; 3 4 var _stock_info = ['out-of-stock', 'in-short-supply', 'in-stock'], 5 $v, 6 ArticleClass = function () { 7 this.init(); 8 }; 9 10 ArticleClass.DEFAULTS = { 11 input: { 12 id: 'a', 13 childId: 'VariKindArtikel', 14 quantity: 'anzahl' 15 }, 16 action: { 17 compareList: 'Vergleichsliste', 18 compareListRemove: 'Vergleichsliste.remove', 19 wishList: 'Wunschliste', 20 wishListRemove: 'Wunschliste.remove' 21 }, 22 selector: { 23 navUpdateCompare: '#comparelist-dropdown-content', 24 navBadgeUpdateCompare: '#comparelist-badge', 25 navCompare: '#shop-nav-compare', 26 navContainerWish: '#wishlist-dropdown-container', 27 navBadgeWish: '#badge-wl-count', 28 navBadgeAppend: '#shop-nav li.cart-menu', 29 boxContainer: '#sidebox', 30 boxContainerWish: '#sidebox', 31 quantity: 'input.quantity' 32 }, 33 modal: { 34 id: 'modal-article-dialog', 35 wrapper: '#result-wrapper', 36 wrapper_modal: '#result-wrapper-modal' 37 } 38 }; 39 40 ArticleClass.prototype = { 41 modalShown: false, 42 modalView: null, 43 44 constructor: ArticleClass, 45 46 init: function () { 47 this.options = ArticleClass.DEFAULTS; 48 this.gallery = null; 49 }, 50 51 onLoad: function() { 52 if (this.isSingleArticle()) { 53 var that = this; 54 var form = $.evo.io().getFormValues('buy_form'); 55 56 if (typeof history.replaceState === 'function') { 57 history.replaceState({ 58 a: form.a, 59 a2: form.VariKindArtikel || form.a, 60 url: document.location.href, 61 variations: {} 62 }, document.title, document.location.href); 63 } 64 65 window.addEventListener('popstate', function (event) { 66 if (event.state) { 67 that.setArticleContent(event.state.a, event.state.a2, event.state.url, event.state.variations); 68 } 69 }, false); 70 } 71 }, 72 73 isSingleArticle: function() { 74 return $('#buy_form').length > 0; 75 }, 76 77 getWrapper: function(wrapper) { 78 return typeof wrapper === 'undefined' ? $(this.options.modal.wrapper) : $(wrapper); 79 }, 80 81 getCurrent: function($item) { 82 if ($item.hasClass('variation')) { 83 return $item; 84 } 85 let $current = $item.closest('.variation'); 86 let $checked = $item.find('input:checked'); 87 if ($checked.parent().hasClass('variation')) { 88 //swatch and textbox 89 $current = $checked.parent(); 90 } else if ($checked.next().hasClass('variation')) { 91 //radio 92 $current = $checked.next(); 93 } else if ($item.find('option:selected').hasClass('variation')) { 94 //select 95 $current = $item.find('option:selected'); 96 } else if ($current.length === 0) { 97 $current = $item.next('.variation'); 98 } 99 100 return $current; 101 }, 102 103 incrementProductVisitCount: function() { 104 console.log('This function is deprecated since JTL Shop 5.4.0'); 105 }, 106 107 navigateBackToList: function() { 108 console.log('This function is deprecated since JTL Shop 5.4.0'); 109 }, 110 111 register: function(wrapper) { 112 var $wrapper = this.getWrapper(wrapper); 113 114 if (this.isSingleArticle()) { 115 this.registerGallery($wrapper); 116 this.registerConfig(); 117 this.registerHoverVariations($wrapper); 118 } 119 120 this.registerSimpleVariations($wrapper); 121 this.registerSwitchVariations($wrapper); 122 this.registerBulkPrices($wrapper); 123 this.registerAccordion(); 124 // this.registerImageSwitch($wrapper); 125 this.registerArticleOverlay($wrapper); 126 this.registerImageHover($wrapper); 127 this.registerFinish($wrapper); 128 window.initNumberInput(); 129 this.initAbnahmeIntervallError(); 130 this.setClickableProductbox(); 131 }, 132 133 setClickableProductbox: function() { 134 $('.productbox[tabindex="0"]').on('keydown', function(e) { 135 // on Enter or Space 136 if (e.keyCode === 13 || e.keyCode === 32) { 137 e.preventDefault(); 138 $(this).find('a')[0].click(); 139 } 140 }); 141 }, 142 143 registerAccordion: function() { 144 $('.is-mobile .accordion [id^="tab-"]').on('shown.bs.collapse', function () { 145 let self = $(this); 146 $.evo.destroyScrollSearchEvent(); 147 setTimeout(function() { 148 $('html').animate( 149 {scrollTop: self.offset().top-40}, 150 100, 151 'linear', 152 function () { 153 setTimeout(function() { 154 $.evo.initScrollSearchEvent(); 155 }, 500); 156 }); 157 }, 400); 158 }); 159 }, 160 161 registerArticleOverlay: function($wrapper) { 162 var that = this; 163 164 $('.configpreview', $wrapper) 165 .each(function(i, item) { 166 let $item = $(item); 167 let wrapper = that.options.modal.wrapper_modal + '_modal'; 168 169 $item.on('click', function (event) { 170 event.preventDefault(); 171 that.modalArticleDetail(this, wrapper); 172 }); 173 }); 174 $wrapper.hover(null, function() { 175 $(this).removeClass('active'); 176 }) 177 }, 178 179 registerGallery: function(wrapper) { 180 /* 181 * product slider and zoom (details) 182 */ 183 function slickinit() 184 { 185 $('.initial-slick-dots').on('click', function () { 186 let mainNode = $('#gallery'); 187 mainNode.removeClass('slick-lazy'); 188 $.evo.extended().initSlick(mainNode, mainNode.data('slick-type')); 189 if(mainNode.slick('getSlick').slideCount > mainNode.slick('slickGetOption', 'slidesToShow')) { 190 mainNode.slick('slickGoTo', 1); 191 } 192 }); 193 } 194 195 function toggleFullscreen(fullscreen = false) 196 { 197 let $imgWrapper = $('#image_wrapper'), 198 $gallery = $('#gallery'); 199 if (!$gallery.hasClass('slick-initialized') || (fullscreen && $imgWrapper.hasClass('fullscreen'))){ 200 return; 201 } 202 203 let maxHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0
203), 204 otherElemHeight = 0, 205 current = ($('#gallery .slick-current').data('slick-index')), 206 $galleryImages = $('#gallery img, #gallery picture source'), 207 hidePreview = maxHeight < 700, 208 previewHeight = $('#gallery_preview_wrapper').length > 0 && !hidePreview ? 170 : 30, 209 $previewBar = $('.product-detail-image-preview-bar'); 210 211 if (fullscreen) { 212 $imgWrapper.addClass('fullscreen'); 213 let $galleryTopbar = $('#image_wrapper .product-detail-image-topbar'); 214 215 otherElemHeight = $galleryTopbar.outerHeight() 216 + 2*parseInt($imgWrapper.css('paddingTop')) 217 + previewHeight; 218 219 $galleryImages.removeAttr('sizes'); 220 // lazySizes.autoSizer.updateElem($galleryImages); 221 222 if (hidePreview) { 223 $previewBar.addClass('d-none'); 224 } 225 226 $galleryImages.css('max-height', maxHeight-otherElemHeight); 227 $gallery.css('max-height', maxHeight-otherElemHeight); 228 229 $('body').off('click.toggleFullscreen').on('click.toggleFullscreen', function (event) { 230 if (!($(event.target).hasClass('product-image') || $(event.target).hasClass('slick-arrow'))) { 231 toggleFullscreen(false); 232 $('body').off('click.toggleFullscreen'); 233 } 234 }); 235 } else { 236 $imgWrapper.removeClass('fullscreen'); 237 $galleryImages.css('max-height', '100%'); 238 $gallery.css('max-height', '100%'); 239 $previewBar.removeClass('d-none'); 240 } 241 242 $gallery.slick('slickSetOption','initialSlide', current, true); 243 $('#gallery_preview').slick('slickGoTo', current, true); 244 245 //fix firefox height bug 246 $('.slick-slide, .slick-arrow').css({'display': 'none'}); 247 setTimeout(function(){ 248 $('.slick-slide, .slick-arrow').css({'display': 'block'}); 249 }, 50); 250 } 251 252 function addClickListener() { 253 $('#gallery img').off('click').on('click', e => { 254 if (window.innerWidth > globals.breakpoints.lg) { 255 toggleFullscreen(true); 256 } 257 }); 258 } 259 260 slickinit(); 261 262 if (wrapper[0].id.indexOf(this.options.modal.wrapper_modal.slice(1)) === -1) { 263 addClickListener(); 264 265 $(document).on('keyup', e => { 266 if (e.key === "Escape" && $('#image_wrapper').hasClass('fullscreen')) { 267 toggleFullscreen(); 268 addClickListener(); 269 } 270 }); 271 } 272 }, 273 274 registerConfig: function() { 275 var that = this, 276 config = $('#product-configurator') 277 .closest('form') 278 .find('input[type="radio"], input[type="text"], input[type="checkbox"], input[type="number"], select'), 279 dropdown = $('#product-configurator') 280 .closest('form') 281 .find('select'); 282 let offset = $('#jtl-nav-wrapper').height(); 283 284 if (dropdown.length > 0) { 285 dropdown.on('change', function () { 286 var item = $(this).val(); 287 $(this).parents('.cfg-group').find('.cfg-drpdwn-item.collapse.show').collapse('hide'); 288 $('#drpdwn_qnt_' + item).collapse('show'); 289 }) 290 } 291 292 if (config.length > 0) { 293 config.on('change', function() { 294 that.configurator(); 295 }) 296 .on('keypress', function (e) { 297 if (e.key === 'Enter') { 298 return false;
299 } 300 }); 301 // timeout fixes problem with loading order of bootstrap dropdowns 302 setTimeout(function(){ 303 that.configurator(true); 304 },0); 305 } 306 307 function scroll (selector) { 308 $(selector).bind('click', function(event) { 309 event.preventDefault(); 310 let anchor = $(this).attr('href'); 311 $('html, body').stop().animate({ 312 scrollTop: $(anchor).offset().top - offset - 15 313 }); 314 }); 315 } 316 scroll('a[href="#cfg-container"]'); 317 318 319 $('#cfg-nav nav a').on('click', function() { 320 $('html, body').animate({ 321 scrollTop: $('#cfg-container').offset().top - offset - 15 322 }); 323 let anchor = $(this).attr('href'), 324 elOffset = $(anchor)[0].offsetTop; 325 $('#cfg-container .cfg-options').stop().animate({ 326 scrollTop: elOffset 327 }); 328 }); 329 330 $(document).on('scroll', function (e) { 331 let headerHeight = $('#jtl-nav-wrapper').outerHeight() + 10; 332 $('.cfg-position-details.cfg-layout-list #product-configuration-sidebar, ' + 333 '.cfg-position-details.cfg-layout-list .cfg-group .cfg-group-info').css('top', headerHeight + 'px'); 334 }); 335 }, 336 337 registerSimpleVariations: function($wrapper) { 338 var that = this; 339 340 $('.variations select', $wrapper).selectpicker({ 341 iconBase: 'fa', 342 tickIcon: 'fa-check', 343 hideDisabled: true, 344 showTick: true 345 }); 346 347 $('.simple-variations input[type="radio"]', $wrapper) 348 .on('change', function() { 349 var val = $(this).val(), 350 key = $(this).parent().data('key'); 351 $('.simple-variations [data-key="' + key + '"]').removeClass('active'); 352 $('.simple-variations [data-value="' + val + '"]').addClass('active'); 353 $(this).closest(".swatches").addClass("radio-selected"); 354 }); 355 356 $('.simple-variations input[type="radio"], .simple-variations select', $wrapper) 357 .each(function(i, item) { 358 var $item = $(item), 359 wrapper = '#' + $item.closest('form').closest('div[data-wrapper="true"]').attr('id'); 360 361 $item.on('change', function () { 362 that.variationPrice($(this), true, wrapper); 363 }); 364 }); 365 $('.simple-variations input[type="text"]', $wrapper) 366 .each(function(i, item) { 367 let $item = $(item), 368 wrapper = '#' + $item.closest('form').closest('div[data-wrapper="true"]').attr('id'), 369 timeout = null; 370 $item.on('keyup', function (e) { 371 clearTimeout(timeout); 372 let self = $(this); 373 374 timeout = setTimeout(function () { 375 that.variationPrice(self, true, wrapper); 376 }, 500); 377 }); 378 }); 379 }, 380 381 registerBulkPrices: function($wrapper) { 382 var $bulkPrice = $('.bulk-price', $wrapper), 383 that = this, 384 $config = $('#product-configurator'); 385 386 if (($bulkPrice.length > 0 && $config.length === 0) || $('#product-list').length > 0) { 387 $('#quantity, [data-bulk="1"] .quantity', $wrapper) 388 .each(function(i, item) { 389 let $item = $(item), 390 wrapper = '#' + $item.closest('form').closest('div[data-wrapper="true"]').attr('id'); 391 392 $item.on('change', function () { 393 that.variationPrice($(this), true, wrapper); 394 }); 395 that.variationPrice($(this), true, wrapper); 396 }); 397 } 398 }, 399 400 registerSwitchVariations: function($wrapper) { 401 var that = this; 402 403 $('.switch-variations input[type="radio"], .switch-variations select', $wrapper) 404 .each(function(i, item) { 405 var $item = $(item), 406 /* niu switched*/ 407 /*wrapper = '#' + $item.closest('form').closest('div[id]').attr('id');*/ 408 wrapper = '#' + $item.closest('form').closest('div[data-wrapper="true"]').attr('id'); 409 410 $item.on('change', function () { 411 that.variationSwitch($(this), false, wrapper); 412 }); 413 }); 414 415 if (isTouchCapable()) { 416 $('.variations .swatches .variation', $wrapper) 417 .on('mouseover', function() { 418 $(this).trigger('click'); 419 }); 420 } 421 422 // ie11 fallback 423 if (typeof document.body.style.msTransform === 'string') { 424 $('.variations label.variation', $wrapper) 425 .on('click', function (e) { 426 if (e.target.tagName === 'IMG') { 427 $(this).trigger('click'); 428 } 429 }); 430 } 431 }, 432 433 registerHoverVariations: function ($wrapper) { 434 let delay=300, setTimeoutConst; 435 $('.variations label.variation', $wrapper) 436 .on('mouseenter', function (e) { 437 setTimeoutConst = setTimeout(function () { 438 let $mainImage = $('[data-niu-lightbox-trigger]') 439 let mainImageHeight = $mainImage.innerHe
439ight(); 440 let mainImageWidth = ($mainImage.innerWidth() || 593) + 'px'; 441 let target = $('.variation-image-preview.vt' + $(e.currentTarget).data('value')) 442 let content = $('#content') 443 target.addClass('show d-md-block') 444 /*target.css('top', $(e.currentTarget).offset().top - $(e.currentTarget).closest('#content').position().top - mainImageHeight / 2 - 12);*/ 445 /*target.css('top', $(e.currentTarget).offset().top - $(e.currentTarget).closest('#content').position().top - mainImageHeight / 2 - 12);*/ 446 if($mainImage.offset().top - target.offset().top > 1){ 447 448 target.css('top', $mainImage.offset().top - target.offset().top + 'px'); 449 } 450 target.css('width',mainImageWidth) 451 }, delay) 452 }) 453 .on('mouseleave', function (e) { 454 clearTimeout(setTimeoutConst); 455 $('.variation-image-preview.vt' + $(this).data('value')).removeClass('show d-md-block'); 456 }); 457 458 $('.variations .selectpicker') 459 .on('show.bs.select', function () { 460 let selectPicker = $(this); 461 $(this).parent().find('li .variation') 462 .on('mouseenter', function (e) { 463 setTimeoutConst = setTimeout(function () { 464 let mainImageHeight = $('.js-gallery-images').innerHeight(); 465 let selectOptionValue = selectPicker.find('option').eq( 466 e.currentTarget.ariaPosInSet 467 ).data("value"); 468 $('.variation-image-preview.vt' + selectOptionValue) 469 .addClass('show d-md-block') 470 .css('top', $(e.currentTarget).offset().top - $(e.currentTarget).closest('#content').position().top - mainImageHeight / 2 - 12); 471 }, delay) 472 }) 473 .on('mouseleave', function (e) { 474 clearTimeout(setTimeoutConst); 475 let selectOptionValue = selectPicker.find('option').eq( 476 e.currentTarget.ariaPosInSet 477 ).data("value"); 478 $('.variation-image-preview.vt' + selectOptionValue) 479 .removeClass('show d-md-block'); 480 }); 481 }) 482 .on('hide.bs.select', function () { 483 $(this).parent().find('li .variation').off('mouseenter mouseleave'); 484 $('.variation-image-preview').removeClass('show'); 485 }); 486 }, 487 488 registerImageSwitch: function($wrapper) { 489 var that = this, 490 imgSwitch, 491 gallery = this.gallery; 492 493 if (gallery !== null) { 494 imgSwitch = function (context, temporary, force) { 495 var $context = $(context), 496 id = $context.attr('data-key'), 497 value = $context.attr('data-value'), 498 data = $context.data('list'), 499 title = $context.attr('data-title'); 500 501 if (typeof temporary === 'undefined') { 502 temporary = true; 503 } 504 505 if ((!$context.hasClass('active') || force) && !!data) { 506 gallery.setItems([data], value); 507 508 if (!temporary) { 509 var items = [data], 510 stacks = gallery.getStacks(); 511 for (var s in stacks) { 512 if (stacks.hasOwnProperty(s) && s.match(/^_[0-9a-zA-Z]*$/) && s !== '_' + id) { 513 items = $.merge(items, stacks[s]); 514 } 515 } 516 517 gallery.setItems([data], '_' + id); 518 gallery.setItems(items, '__'); 519 gallery.render('__'); 520 521 that.galleryIndex = gallery.index; 522 that.galleryLastIdent = gallery.ident; 523 } else { 524 gallery.render(value); 525 } 526 } 527 } 528 } else { 529 imgSwitch = function (context, temporary) { 530 var $context = $(context), 531 value = $context.attr('data-value'), 532 data = $context.data('list'), 533 title = $context.attr('data-title'); 534 535 if (typeof temporary === 'undefined') { 536 temporary = true; 537 } 538 539 if (!!data) { 540 var $wrapper = $(context).closest('.product-wrapper'), 541 $img = $('.image-box img', $wrapper); 542 if ($img.length === 1) { 543 $img.attr('src', data.md.src); 544 if (!temporary) { 545 $img.data('src', data.md.src); 546 } 547 } 548 } 549 }; 550 } 551 552 $('.variations .bootstrap-select select', $wrapper) 553 .on('change', function() { 554 var sel = $(this).find('[value=' + this.value + ']'), 555 cont = $(this).closest('.variations'); 556 557 if (cont.hasClass('simple-variations')) { 558 imgSwitch(sel, false, false); 559 } else { 560 imgSwitch(sel, true, false); 561 } 562 }); 563 564 if (!isTouchCapable() || ResponsiveBootstrapToolkit.current() !== 'xs') { 565 $('.variations .bootstrap-select .dropdown-menu li', $wrapper) 566 .on('hover', function () { 567 var tmp_idx = parseInt($(this).attr('data-original-index')) + 1, 568 rule = 'select option:nth-child(' + tmp_idx + ')', 569 sel = $(this).closest('.bootstrap-select').find(rule); 570 imgSwitch(sel); 571 }, function () { 572 var tmp_idx = parseInt($(this).attr('data-original-index')) + 1, 573 rule = 'select option:nth-child(' + tmp_idx + ')', 574 sel = $(this).closest('.bootstrap-select').find(rule), 575 gallery = that.gallery, 576 active; 577 578 if (gallery !== null) { 579 active = $(sel).find('.variation.active'); 580 gallery.render(that.galleryLastIdent); 581 gallery.activate(that.galleryIndex); 582 } else { 583 var $wrapper = $(sel).closest('.product-wrapper'), 584 $img = $('.image-box img', $wrapper); 585 if ($img.length === 1) { 586 $img.attr('src', $img.data('src')); 587 } 588 } 589 }); 590 } 591 592 $('.variations.simple-variations .variation', $wrapper) 593 .on('click', function () { 594 imgSwitch(this, false); 595 }); 596 597 if (!isTouchCapable() || ResponsiveBootstrapToolkit.current() !== 'xs') { 598 $('.variations .variation', $wrapper) 599 .on('hover', function () { 600 imgSwitch(this); 601 }, function () { 602 var sel = $(this).closest('.variation'), 603 gallery = that.gallery; 604 605 if (gallery !== null) { 606 gallery.render(that.galleryLastIdent); 607 gallery.activate(that.galleryIndex); 608 } else { 609 var $wrapper = $(sel).closest('.product-wrapper'), 610 $img = $('.image-box img', $wrapper); 611 if ($img.length === 1) { 612 $img.attr('src', $img.data('src')); 613 } 614 } 615 }); 616 } 617 }, 618 619 registerImageHover: function($wrapper) { 620 $('.product-list .productbox-hover:not(.focus), .product-list .productbox-show-variations:not(.focus)', 621 $wrapper).on('mouseenter focusin', function () { 622 $(this).closest('.product-list').find('.focus').removeClass('focus'); 623 }); 624 $('.productbox-show-variations', $wrapper).on('mouseenter focusin', function () { 625 let collapse = $(this).find('.productbox-variations>.collapse') 626 627 $(this).addClass('focus'); 628 $(collapse).collapse('show'); 629 }); 630 $('.productlist-page-nav', $wrapper).on('focusin', function () { 631 $('.productbox-show-variations.focus', $wrapper).removeClass('focus'); 632 }); 633 $('.productbox-show-variations', $wrapper).on(' mouseleave', function () { 634 let collapse = $(this).not('.focus').find('.productbox-variations>.collapse') 635 let box = $(this) 636 637 box.removeClass('focus'); 638 if (collapse.length === 1) { 639 box.addClass('transition'); 640 $(collapse).collapse('hide'); 641 $(collapse).on('hidden.bs.collapse', function () { 642 box.removeClass('transition'); 643 }); 644 } 645 }); 646 $('.is-mobile .show-variation-collapse a').on('click', function (e) { 647 if (!$(this).closest('.show-variation-collapse').find('.collapse').hasClass('show')) { 648 e.preventDefault(); 649 } 650 }); 651 }, 652 653 registerFinish: function($wrapper) { 654 $('#jump-to-votes-tab', $wrapper).on('click', function () { 655 let $tabID = $('#content a[href="#tab-votes"]'); 656 if ($tabID.length > 0) { 657 $tabID.tab('show'); 658 } else { 659 $tabID = $('#tab-votes'); 660 $tabID.collapse('show'); 661 } 662 663 $([document.documentElement, document.body]).animate({ 664 scrollTop: $tabID.offset().top 665 }, 200); 666 }); 667 668 let $tabID = $('#product-tabs a[href="' + window.location.hash + '"]'); 669 if ($tabID.length) { 670 $tabID.tab('show'); 671 $([document.documentElement, document.body]).animate({ 672 scrollTop: $tabID.offset().top 673 }, 200); 674 } 675 676 if (this.isSingleArticle()) { 677 if ($('.switch-variations .form-group', $wrapper).length === 1) { 678 var wrapper = '#' + $($wrapper).attr('id'); 679 this.variationSwitch($('.switch-variations', $wrapper), false, wrapper); 680 } 681 } 682 else { 683 var that = this; 684 685 $('.product-cell.hover-enabled') 686 .on('click', function (event) { 687 if (isTouchCapable() && ResponsiveBootstrapToolkit.current() !== 'xs') { 688 var $this = $(this); 689 690 if (!$this.hasClass('active')) { 691 event.preventDefault(); 692 event.stopPropagation(); 693 $('.product-cell').removeClass('active'); 694 $this.addClass('active'); 695 } 696 } 697 }) 698 .on('mouseenter', function (event) { 699 var $this = $(this), 700 wrapper = '#' + $this.attr('id'); 701 702 if (!$this.data('varLoaded') && $('.switch-variations .form-group', $this).length === 1) { 703 that.variationSwitch($('.switch-variations', $this), false, wrapper); 704 } 705 $this.data('varLoaded', true); 706 }); 707 } 708 709 this.registerProductActions($('#sidepanel_left')); 710 this.registerProductActions($('#footer')); 711 this.registerProductActions($('#shop-nav')); 712 this.registerProductActions($wrapper); 713 this.registerProductActions('#cart-form'); 714 dzm.dispatcher.dispatch(dzm.events.jtl.article.checkVarkombiDependencies,null); 715 716 }, 717 718 registerProductActions: function($wrapper) { 719 var that = this; 720 721 $('*[data-toggle="product-actions"] button', $wrapper) 722 .on('click', function(event) { 723 var data = $(this.form).serializeObject(); 724 725 if ($wrapper === '#cart-form') { 726 data.wlPos = $(this).data('wl-pos'); 727 data.a = $(this).data('product-id-wl'); 728 } 729 730 if (that.handleProductAction(this, data)) { 731 event.preventDefault(); 732 } 733 }); 734 $('a[data-toggle="product-actions"]', $wrapper) 735 .on('click', function(event) { 736 var data = $(this).data('value'); 737 this.name = $(this).data('name'); 738 739 if (that.handleProductAction(this, data)) { 740 event.preventDefault(); 741 } 742 }); 743 }, 744
745 loadModalArticle: function(url, wrapper, done, fail) { 746 var that = this, 747 id = wrapper.slice(1), 748 $modalBody = $('.modal-body', this.modalView); 749 750 $.ajax(url, {data: {'isAjax':1, 'quickView':1}}) 751 .done(function(data) { 752 var $html = $('<div />').html(data); 753 var $headerCSS = $html.find('link[type="text/css"]'); 754 var $headerJS = $html.find('script[src][src!=""]'); 755 var content = $html.find(that.options.modal.wrapper).html(); 756 757 $headerCSS.each(function (pos, item) { 758 var $cssLink = $('head link[href="' + item.href + '"]'); 759 if ($cssLink.length === 0) { 760 $('head').append('<link rel="stylesheet" type="text/css" href="' + item.href + '" >'); 761 } 762 }); 763 764 $headerJS.each(function (pos, item) { 765 if (typeof item.src !== 'undefined' && item.src.length > 0) { 766 var $jsLink = $('head script[src="' + item.src + '"]'); 767 if ($jsLink.length === 0) { 768 $('head').append('<script defer src="' + item.src + '" >'); 769 } 770 } 771 }); 772 773 $modalBody.html($('<div id="' + id + '" />').html(content)); 774 775 var $modal = $modalBody.closest(".modal-dialog"), 776 title = $modal.find('.modal-body h1'), 777 $config = $('#product-configurator', $modalBody); 778 779 if ($config.length > 0) { 780 // Configurator in child article!? Currently not supported! 781 $config.remove(); 782 $.evo.extended().startSpinner($modalBody); 783 location.href = url; 784 } 785 if (title.length > 0 && title.text().length > 0) { 786 $modal.find('.modal-title').text(title.text()); 787 title.remove(); 788 } 789 790 $('form', $modalBody).on('submit', function(event) { 791 event.preventDefault(); 792 793 var $form = $(this); 794 var data = $form.serializeObject(); 795 if (data['VariKindArtikel']) { 796 data['a'] = data['VariKindArtikel']; 797 } 798 799 $.evo.basket().addToBasket($form, data); 800 that.modalView.modal('hide'); 801 }); 802 803 if (typeof done === 'function') { 804 done(); 805 } 806 }) 807 .fail(function() { 808 if (typeof fail === 'function') { 809 fail(); 810 } 811 }) 812 .always(function() { 813 $.evo.extended().stopSpinner(); 814 }); 815 }, 816 817 addToComparelist: function(data, $action) { 818 var productId = parseInt(data[this.options.input.id]); 819 var childId = parseInt(data[this.options.input.childId]); 820 if (childId > 0) { 821 productId = childId; 822 } 823 if (productId > 0) { 824 var that = this; 825 $.evo.io().call('pushToComparelist', [productId], that, function(error, data) { 826 if (error) { 827 return; 828 } 829 830 var response = data.response; 831 832 if (response) { 833 switch (response.nType) { 834 case 0: // error 835 var errorlist = '<ul><li>' + response.cHints.join('</li><li>') + '</li></ul>'; 836 eModal.alert({ 837 title: response.cTitle, 838 message: errorlist, 839 keyboard: true, 840 tabindex: -1,
841 buttons: false 842 }); 843 break; 844 case 1: // forwarding 845 window.location.href = response.cLocation; 846 break; 847 case 2: // added to comparelist 848 that.updateComparelist(response); 849 break; 850 } 851 } 852 }); 853 854 return true; 855 } 856 857 return false; 858 }, 859 860 removeFromCompareList: function(data) { 861 /*niu differ between child and parent, so you can also remove from comparelist*/ 862 var productId = parseInt(data[this.options.input.id]); 863 var childId = parseInt(data[this.options.input.childId]); 864 if (childId > 0) { 865 productId = childId; 866 } 867 if (productId > 0) { 868 var that = this; 869 $.evo.io().call('removeFromComparelist', [productId], that, function(error, data) { 870 if (error) { 871 return; 872 } 873 874 var response = data.response; 875 876 if (response) { 877 switch (response.nType) { 878 case 0: // error 879 var errorlist = '<ul><li>' + response.cHints.join('</li><li>') + '</li></ul>'; 880 eModal.alert({ 881 title: response.cTitle, 882 message: errorlist, 883 keyboard: true, 884 tabindex: -1,
885 buttons: false 886 }); 887 break; 888 case 1: // forwarding 889 window.location.href = response.cLocation; 890 break; 891 case 2: // removed from comparelist 892 that.updateComparelist(response); 893 break; 894 } 895 } 896 }); 897 898 return true; 899 } 900 901 return false; 902 }, 903 904 updateComparelist: function(data) { 905 var $badgeUpd = $(this.options.selector.navUpdateCompare); 906 907 var badge = $(data.navDropdown); 908 $badgeUpd.html(badge); 909 $(this.options.selector.navBadgeUpdateCompare).html(data.nCount); 910 911 if (data.nCount > 0) { 912 $(this.options.selector.navCompare).removeClass('d-none'); 913 } else { 914 $(this.options.selector.navCompare).addClass('d-none'); 915 $('#nav-comparelist-collapse').removeClass('show'); 916 } 917 if (data.nCount > 1) { 918 $('#nav-comparelist-goto').removeClass('d-none'); 919 } else { 920 $('#nav-comparelist-goto').addClass('d-none'); 921 } 922 this.registerProductActions($('#shop-nav')); 923 924 if (data.productID) { 925 let $action = $('button[data-product-id-cl="' + data.productID + '"]') 926 $action.removeClass("on-list"); 927 $action.next().removeClass("press"); 928 $('.comparelist [data-product-id-cl="' + data.productID + '"]').remove(); 929 } 930 931 for (var ind in data.cBoxContainer) { 932 var $list = $(this.options.selector.boxContainer+ind); 933 934 if ($list.length > 0) { 935 if (data.cBoxContainer[ind].length) { 936 var $boxContent = $(data.cBoxContainer[ind]); 937 this.registerProductActions($boxContent); 938 $list.replaceWith($boxContent).removeClass('d-none'); 939 } else { 940 $list.html('').addClass('d-none'); 941 } 942 } 943 } 944 }, 945 946 addToWishlist: function(data, $action) { 947 let productId = parseInt(data[this.options.input.id]), 948 childId = parseInt(data[this.options.input.childId]), 949 qty = parseFloat(data[this.options.input.quantity]); 950 if (childId > 0) { 951 productId = childId; 952 } 953 if (isNaN(qty)) { 954 qty = 1; 955 } 956 if (productId > 0) { 957 var that = this; 958 $.evo.io().call('pushToWishlist', [productId, qty, data], that, function(error, data) { 959 if (error) { 960 $action.closest('form')[0].reportValidity(); 961 return; 962 } 963 if ($action.hasClass('action-tip-animation-b')) { 964 $action.addClass("on-list"); 965 $action.next().addClass("press"); 966 $action.next().next().removeClass("press"); 967 } 968 var response = data.response; 969 970 if (response) { 971 switch (response.nType) { 972 case 0: // error 973 var errorlist = '<ul><li>' + response.cHints.join('</li><li>') + '</li></ul>'; 974 eModal.alert({ 975 title: response.cTitle, 976 message: errorlist, 977 keyboard: true, 978 tabindex: -1,
979 buttons: false 980 }); 981 break; 982 case 1: // forwarding 983 window.location.href = response.cLocation; 984 break; 985 case 2: // added to wishlist 986 that.updateWishlist(response); 987 break; 988 } 989 } 990 }); 991 992 return true; 993 } 994 995 return false; 996 }, 997 998 removeFromWishList: function(data) { 999 var productId = parseInt(data[this.options.input.id]); 1000 if (productId > 0) { 1001 var that = this; 1002 $.evo.io().call('removeFromWishlist', [productId], that, function(error, data) { 1003 if (error) { 1004 return; 1005 } 1006 1007 var response = data.response; 1008 1009 if (response) { 1010 switch (response.nType) { 1011 case 0: // error 1012 var errorlist = '<ul><li>' + response.cHints.join('</li><li>') + '</li></ul>'; 1013 eModal.alert({ 1014 title: response.cTitle, 1015 message: errorlist, 1016 keyboard: true, 1017 tabindex: -1,
1018 buttons: false 1019 }); 1020 break; 1021 case 1: // forwarding 1022 window.location.href = response.cLocation; 1023 break; 1024 case 2: // removed from wishlist 1025 that.updateWishlist(response); 1026 break; 1027 } 1028 } 1029 }); 1030 1031 return true; 1032 } 1033 1034 return false; 1035 }, 1036 1037 updateWishlist: function(data) { 1038 var $navContainerWish = $(this.options.selector.navContainerWish); 1039 var $navBadgeWish = $(this.options.selector.navBadgeWish); 1040 1041 if (data.wlPosRemove) { 1042 let $action = $('button[data-wl-pos="' + data.wlPosRemove + '"]'); 1043 $action.removeClass("on-list"); 1044 $action.next().removeClass("press"); 1045 $action.find('.wishlist-icon').addClass('far').removeClass('fas'); 1046 } 1047 if (data.wlPosAdd) { 1048 let $action = $('button[data-product-id-wl="' + data.productID + '"]'); 1049 $action.attr('data-wl-pos', data.wlPosAdd); 1050 $action.data('wl-pos', data.wlPosAdd); 1051 $action.closest('form').find('input[name="wlPos"]').val(data.wlPosAdd) 1052 $action.find('.wishlist-icon').addClass('fas').removeClass('far'); 1053 } 1054 $.evo.io().call('updateWishlistDropdown', [$navContainerWish, $navBadgeWish], this, function(error, data) { 1055 if (error) { 1056 return; 1057 } 1058 if (data.response.currentPosCount > 0) { 1059 $navBadgeWish.removeClass('d-none'); 1060 } else { 1061 $navBadgeWish.addClass('d-none'); 1062 } 1063 $navContainerWish.html(data.response.content); 1064 $navBadgeWish.html(data.response.currentPosCount); 1065 setClickableRow(); 1066 }); 1067 1068 for (var ind in data.cBoxContainer) { 1069 var $list = $(this.options.selector.boxContainerWish+ind); 1070 if ($list.length > 0) { 1071 if (data.cBoxContainer[ind].length) { 1072 var $boxContent = $(data.cBoxContainer[ind]); 1073 this.registerProductActions($boxContent); 1074 $list.replaceWith($boxContent).removeClass('d-none'); 1075 } else { 1076 $list.html('').addClass('d-none'); 1077 } 1078 } 1079 } 1080 }, 1081 1082 handleProductAction: function(action, data) { 1083 let $action = $(action); 1084 switch (action.name) { 1085 case this.options.action.compareList: 1086 if ($action.hasClass('action-tip-animation-b')) { 1087 if ($action.hasClass('on-list')) { 1088 $action.removeClass("on-list"); 1089 $action.next().removeClass("press"); 1090 $action.next().next().addClass("press"); 1091 return this.removeFromCompareList(data); 1092 } else { 1093 $action.addClass("on-list"); 1094 $action.next().addClass("press"); 1095 $action.next().next().removeClass("press"); 1096 $(this.options.selector.navCompare).removeClass('d-none'); 1097 1098 let $moveTo = isMobileByBodyClass() 1099 ? $('.wish-compare-animation-mobile #burger-menu') 1100 : $('.wish-compare-animation-desktop #shop-nav-compare'); 1101 $.evo.article().moveItemAnimation($action, $moveTo); 1102 1103 return this.addToComparelist(data, $action); 1104 } 1105 } else { 1106 return this.addToComparelist(data, $action); 1107 } 1108 case this.options.action.compareListRemove: 1109 return this.removeFromCompareList(data); 1110 case this.options.action.wishList: 1111 data[this.options.input.quantity] = $('input[data-product-id="' + data.a + '"]').val() 1112 || $('#buy_form_'+data.a+' '+this.options.selector.quantity).val() 1113 || $('#quantity').val(); 1114 if ($action.hasClass('on-list')) { 1115 $action.removeClass("on-list"); 1116 $action.next().removeClass("press"); 1117 $action.next().next().addClass("press"); 1118 data.a = data.wlPos; 1119 return this.removeFromWishList(data); 1120 } else { 1121 $action.addClass("on-list"); 1122 let $moveTo = isMobileByBodyClass() 1123 ? $('.wish-compare-animation-mobile #burger-menu') 1124 : $('.wish-compare-animation-desktop #shop-nav-wish');
1125 $.evo.article().moveItemAnimation($action, $moveTo); 1126 return this.addToWishlist(data, $action); 1127 } 1128 case this.options.action.wishListRemove: 1129 return this.removeFromWishList(data); 1130 } 1131 1132 return false; 1133 }, 1134 1135 configurator: function(init) { 1136 if (this.isSingleArticle()) { 1137 var that = this, 1138 container = $('#cfg-container'), 1139 sidebar = $('#cfg-sticky-sidebar'), 1140 width, 1141 form; 1142 1143 if (container.length === 0) { 1144 return; 1145 } 1146 1147 $.evo.extended().startSpinner(container); 1148 1149 $('#buy_form').find('*[data-selected="true"]') 1150 .attr('checked', true) 1151 .attr('selected', true) 1152 .attr('data-selected', null); 1153 1154 form = $.evo.io().getFormValues('buy_form'); 1155 1156 $.evo.io().call('buildConfiguration', [form], that, function (error, data) { 1157 1158 var result, 1159 i, 1160 j, 1161 item, 1162 cBeschreibung, 1163 quantityWrapper, 1164 grp, 1165 value, 1166 enableQuantity, 1167 nNetto, 1168 quantityInput; 1169 $('.js-start-configuration').prop('disabled', !(data.response.variationsSelected && data.response.inStock)); 1170 $('.js-choose-variations-wrapper').toggleClass('d-none', data.response.variationsSelected); 1171 $('.js-cfg-group').each(function (i, item) { 1172 let iconChecked = $('a[href="#'+this.id+'"] .js-group-checked'), 1173 badgeInfoDanger = 'alert-info'; 1174 if (data.response.invalidGroups && data.response.invalidGroups.includes($(this).data('id'))) { 1175 iconChecked.addClass('d-none'); 1176 if ($(this).hasClass('visited')) { 1177 badgeInfoDanger = 'alert-danger'; 1178 } 1179 $(this).find('[data-niu-configurator-next-btn]').prop("disabled",true); 1180 $(this).find('.js-group-badge-checked') 1181 .removeClass('alert-success alert-info') 1182 .addClass(badgeInfoDanger); 1183 } else { 1184 iconChecked.removeClass('d-none'); 1185 $(this).find('[data-niu-configurator-next-btn]').prop("disabled",false); 1186 1187 $(this).find('.js-group-badge-checked') 1188 .addClass('alert-success') 1189 .removeClass('alert-danger alert-info'); 1190 } 1191 }); 1192 $('.js-cfg-group-error').addClass('d-none').html(''); 1193 $.each(data.response.errorMessages, function (i, item) { 1194 $('.js-cfg-group-error[data-id="' + item.group + '"]').removeClass('d-none').html(item.message); 1195 }); 1196 let $summaryFinish = $('#cfg-tab-summary-finish'); 1197 if (data.response.valid) { 1198 $('.js-cfg-validate').prop('disabled', false); 1199 $summaryFinish.children().removeClass('disabled'); 1200 $summaryFinish.removeClass('disabled'); 1201 } else { 1202 $('.js-cfg-validate').prop('disabled', true); 1203 $summaryFinish.children().addClass('disabled'); 1204 $summaryFinish.addClass('disabled'); 1205 } 1206 $.evo.extended().stopSpinner(); 1207 if (error) { 1208 $.evo.error(data); 1209 return; 1210 } 1211 result = data.response; 1212 1213 if (!result.oKonfig_arr) { 1214 $.evo.error('Missing configuration groups'); 1215 return; 1216 } 1217 1218 // global price 1219 nNetto = result.nNettoPreise; 1220 that.setPrice(result.fGesamtpreis[nNetto], result.cPreisLocalized[nNetto], result.cPreisString); 1221 that.setStockInformation(result.cEstimatedDelivery); 1222 1223 $('#content .summary').html(result.cTemplate); 1224 $.evo.tooltips(); 1225 $.evo.extended() 1226 .trigger('priceChanged', result); 1227 }); 1228 } 1229 }, 1230 1231 initConfigListeners: function () { 1232 $('.js-cfg-group').on('click', function () { 1233 $(this).addClass('visited'); 1234 }); 1235 $('#cfg-tab-summary-finish').on('click', function () { 1236 if (!$(this).hasClass('disabled')) { 1237 $('#cfg-modal-tabs').find('.nav-link').removeClass('active'); 1238 $('#cfg-tab-summary').children().addClass('active'); 1239 $(this).children().removeClass('active'); 1240 } 1241 }); 1242 $('.js-cfg-group-collapse').on('click', function () { 1243 $(this).addClass('visited'); 1244 }); 1245 }, 1246 1247 variationRefreshAll: function($wrapper) { 1248 $('.variations select', $wrapper).selectpicker('refresh'); 1249 $.evo.initSliders() 1250 }, 1251 1252 getConfigGroupQuantity: function (groupId) { 1253 return $('.cfg-group[data-id="' + groupId + '"] .quantity'); 1254 }, 1255 1256 getConfigGroupQuantityInput: function (groupId) { 1257 return $('.cfg-group[data-id="' + groupId + '"] .quantity input'); 1258 }, 1259 1260 getConfigGroupImage: function (groupId) { 1261 return $('.cfg-group[data-id="' + groupId + '"] .group-image img'); 1262 }, 1263 1264 setConfigItemImage: function (groupId, img) { 1265 $('.cfg-group[data-id="' + groupId + '"] .group-image img').attr('src', img).first(); 1266 }, 1267 1268 setConfigItemDescription: function (groupId, itemBeschreibung) { 1269 var groupItems = $('.cfg-group[data-id="' + groupId + '"] .group-items'); 1270 var descriptionDropdownContent = groupItems.find('#filter-collapsible_dropdown_' + groupId + ''); 1271 var descriptionDropdownContentHidden = groupItems.find('.d-none'); 1272 var descriptionCheckdioContent = groupItems.find('div[id^="filter-collapsible_checkdio"]'); 1273 var multiselect = groupItems.find('select').attr("multiple"); 1274 1275 // Bisher kein Content mit einer Beschreibung vorhanden, aber ein Artikel mit Beschreibung ausgewählt 1276 if (descriptionDropdownContentHidden.length > 0 && descriptionCheckdioContent.length === 0 && itemBeschreibung.length > 0 && multiselect !== "multiple") { 1277 groupItems.find('a[href="#filter-collapsible_dropdown_' + groupId + '"]').removeClass('d-none'); 1278 descriptionDropdownContent.replaceWith('<div id="filter-collapsible_dropdown_' + groupId + '" class="collapse top10 panel-body">' + itemBeschreibung + '</div>'); 1279 // Bisher Content mit einer Beschreibung vorhanden, aber ein Artikel ohne Beschreibung ausgewählt 1280 } else if (descriptionDropdownContentHidden.length === 0 && descriptionCheckdioContent.length === 0 && itemBeschreibung.length === 0 && multiselect !== "multiple") { 1281 groupItems.find('a[href="#filter-collapsible_dropdown_' + groupId + '"]').addClass('d-none'); 1282 descriptionDropdownContent.addClass('d-none'); 1283 // Bisher Content mit einer Beschreibung vorhanden und ein Artikel mit Beschreibung ausgewählt 1284 } else if (descriptionDropdownContentHidden.length === 0 && descriptionCheckdioContent.length === 0 && itemBeschreibung.length > 0 && multiselect !== "multiple") { 1285 descriptionDropdownContent.replaceWith('<div id="filter-collapsible_dropdown_' + groupId + '" class="collapse top10 panel-body">' + itemBeschreibung + '</div>'); 1286 } 1287 }, 1288 1289 setPrice: function(price, fmtPrice, priceLabel, wrapper) { 1290 var $wrapper = this.getWrapper(wrapper); 1291 1292 if (this.isSingleArticle()) { 1293 $('#product-offer .price', $wrapper).html(fmtPrice); 1294 $('#product-offer meta[itemprop="price"]', $wrapper).attr('content',price); 1295 if (priceLabel.length > 0) { 1296 $('#product-offer .price_label', $wrapper).html(priceLabel); 1297 } 1298 } else { 1299 var $price = $('.price_wrapper', $wrapper); 1300 1301 $('.price span:first-child', $price).html(fmtPrice); 1302 if (priceLabel.length > 0) { 1303 $('.price_label', $price).html(priceLabel); 1304 } 1305 } 1306 1307 $.evo.trigger('changed.article.price', { price: price }); 1308 }, 1309 1310 setStockInformation: function(cEstimatedDelivery, wrapper) { 1311 var $wrapper = this.getWrapper(wrapper); 1312 1313 /* niu switched to our classes */ 1314 /*$('.delivery-status .estimated-delivery span', $wrapper).html(cEstimatedDelivery);*/ 1315 $('.niu-estimated-delivery-wrapper .estimated_delivery span', $wrapper).html(cEstimatedDelivery); 1316 }, 1317 1318 setStaffelPrice: function(prices, fmtPrices, wrapper) { 1319 var $wrapper = this.getWrapper(wrapper), 1320 $container = $('#product-offer', $wrapper); 1321 1322 $.each(fmtPrices, function(index, value){ 1323 $('.bulk-price-' + index + ' .bulk-price', $container).html(value); 1324 }); 1325 }, 1326
1327 setVPEPrice: function(fmtVPEPrice, VPEPrices, fmtVPEPrices, wrapper) { 1328 let $wrapper = this.getWrapper(wrapper); 1329 if ($('#product-offer').length > 0) { 1330 $wrapper = $('#product-offer', $wrapper); 1331 } 1332 1333 $('.base-price .value', $wrapper).html(fmtVPEPrice); 1334 $.each(fmtVPEPrices, function(index, value){ 1335 $('.bulk-price-' + index + ' .bulk-base-price', $wrapper).html(value); 1336 }); 1337 }, 1338 1339 /** 1340 * @deprecated since 4.05 - use setArticleWeight instead 1341 */ 1342 setUnitWeight: function(UnitWeight, newUnitWeight) { 1343 $('#article-tabs .product-attributes .weight-unit').html(newUnitWeight); 1344 }, 1345 1346 setArticleWeight: function(ArticleWeight, wrapper) { 1347 if (this.isSingleArticle()) { 1348 var $articleTabs = $('#article-tabs'); 1349 1350 if ($.isArray(ArticleWeight)) { 1351 $('.product-attributes .weight-unit', $articleTabs).html(ArticleWeight[0][1]); 1352 $('.product-attributes .weight-unit-article', $articleTabs).html(ArticleWeight[1][1]); 1353 } else { 1354 $('.product-attributes .weight-unit', $articleTabs).html(ArticleWeight); 1355 } 1356 } else { 1357 var $wrapper = this.getWrapper(wrapper); 1358 1359 if ($.isArray(ArticleWeight)) { 1360 $('.attr-weight .value', $wrapper).html(ArticleWeight[0][1]); 1361 $('.attr-weight.weight-unit-article .value', $wrapper).html(ArticleWeight[1][1]); 1362 } else { 1363 $('.attr-weight .value', $wrapper).html(ArticleWeight); 1364 } 1365 } 1366 1367 }, 1368 1369 setProductNumber: function(productNumber, wrapper) { 1370 var $wrapper = this.getWrapper(wrapper); 1371 1372 $('#product-offer span[itemprop="sku"]', $wrapper).html(productNumber); 1373 }, 1374 1375 setArticleContent: function(id, variation, url, variations, wrapper) { 1376 var $wrapper = this.getWrapper(wrapper), 1377 listStyle = $('#product-list-type').val(); 1378 1379 if (listStyle === 'undefined') { 1380 listStyle = $('#ed_list.active').length > 0 ? 'list' : 'gallery'; 1381 } 1382 1383 $.evo.extended().startSpinner($wrapper); 1384 1385 if (this.modalShown) { 1386 this.loadModalArticle(url, wrapper, 1387 function() { 1388 var article = new ArticleClass(); 1389 article.register(wrapper); 1390 $.evo.extended().stopSpinner(); 1391 }, 1392 function() { 1393 $.evo.extended().stopSpinner(); 1394 $.evo.error('Error loading ' + url); 1395 } 1396 ); 1397 } else if (this.isSingleArticle()) { 1398 if($('#opc-startmenu').length > 0) { 1399 return this.redirectToArticle(id, variation, url, variations, wrapper); 1400 } 1401 1402 $.evo.extended().loadContent(url, () => { 1403 $.evo.extended().register(); 1404 $.evo.article().register(wrapper); 1405 1406 $(variations).each(function (i, item) { 1407 $.evo.article().variationSetVal(item.key, item.value, wrapper); 1408 }); 1409 1410 if (document.location.href !== url) { 1411 history.pushState({a: id, a2: variation, url: url, variations: variations}, "", url); 1412 } 1413 $.evo.extended().stopSpinner(); 1414 }, function () { 1415 $.evo.error('Error loading ' + url); 1416 $.evo.extended().stopSpinner(); 1417 }, false, wrapper); 1418 } else { 1419 $.evo.extended().loadContent(url + (url.indexOf('?') >= 0 ? '&' : '?') + 'isListStyle=' + listStyle, function (content) { 1420 $.evo.article().register(wrapper); 1421 1422 $('[data-toggle="basket-add"]', $(wrapper)).on('submit', function(event) { 1423 event.preventDefault(); 1424 event.stopPropagation(); 1425 1426 var $form = $(this); 1427 var data = $form.serializeObject(); 1428 data['a'] = variation; 1429 1430 $.evo.basket().addToBasket($form, data); 1431 }); 1432 1433 $(variations).each(function (i, item) {
1434 $.evo.article().variationSetVal(item.key, item.value, wrapper); 1435 }); 1436 1437 $.evo.extended().stopSpinner(); 1438 }, function () { 1439 $.evo.error('Error loading ' + url); 1440 $.evo.extended().stopSpinner(); 1441 }, false, wrapper); 1442 } 1443 }, 1444 1445 redirectToArticle: function(id, variation, url, variations, wrapper) { 1446 var $wrapper = this.getWrapper(wrapper), 1447 listStyle = $('#product-list-type').val(); 1448 1449 $.evo.extended().startSpinner($wrapper); 1450 1451 window.open(url, '_top'); 1452 1453 $.evo.extended().stopSpinner($wrapper); 1454 }, 1455 1456 variationResetAll: function(wrapper) { 1457 var $wrapper = this.getWrapper(wrapper); 1458 1459 $('.variation[data-value] input:checked', $wrapper).prop('checked', false); 1460 $('.variations select option', $wrapper).prop('selected', false); 1461 $('.variations select', $wrapper).selectpicker('refresh'); 1462 }, 1463 1464 variationDisableAll: function(wrapper) { 1465 let $wrapper = this.getWrapper(wrapper); 1466 1467 $('.swatches-selected', $wrapper).text(''); 1468 $('[data-value].variation', $wrapper).each(function(i, item) { 1469 $(item) 1470 .removeClass('active loading') 1471 .addClass('not-available'); 1472 $.evo.article() 1473 .removeStockInfo($(item)); 1474 }); 1475 }, 1476 1477 variationSetVal: function(key, value, wrapper) { 1478 var $wrapper = this.getWrapper(wrapper); 1479 1480 $('[data-key="' + key + '"]', $wrapper).val(value); 1481 }, 1482 1483 variationEnable: function(key, value, wrapper) { 1484 var $wrapper = this.getWrapper(wrapper), 1485 $item = $('[data-value="' + value + '"].variation', $wrapper); 1486 1487 $item.removeClass('not-available swatches-sold-out swatches-not-in-stock'); 1488 }, 1489 1490 showGalleryVariation: function(key, wrapper) { 1491 var $wrapper = this.getWrapper(wrapper), 1492 $item = $('.variation-' + key, $wrapper); 1493 1494 $item.collapse(); 1495 }, 1496 1497 variationActive: function(key, value, def, wrapper) { 1498 var $wrapper = this.getWrapper(wrapper), 1499 $item = $('[data-value="' + value + '"].variation', $wrapper); 1500 $item.addClass('active') 1501 .find('input') 1502 .prop('checked', true) 1503 .end() 1504 .prop('selected', true); 1505 1506 $('[data-id="'+key+'"].swatches-selected') 1507 .text($item.attr('data-original')); 1508 }, 1509 1510 removeStockInfo: function($item) { 1511 var type = $item.attr('data-type'), 1512 elem, 1513 label, 1514 wrapper; 1515 1516 switch (type) { 1517 case 'option': 1518 label = $item.data('content'); 1519 wrapper = $('<div />').append(label); 1520 $(wrapper) 1521 .find('.badge-not-available') 1522 .remove(); 1523 label = $(wrapper).html(); 1524 $item.data('content', label) 1525 .attr('data-content', label); 1526 break; 1527 case 'radio': 1528 elem = $item.find('.badge-not-available'); 1529 if (elem.length === 1) { 1530 $(elem).remove(); 1531 } 1532 break; 1533 case 'swatch': 1534 $item.tooltip('dispose'); 1535 break; 1536 } 1537 $item.removeAttr('data-stock'); 1538 }, 1539 1540 variationInfo: function(value, status, note, notExists) { 1541 let $item = $('[data-value="' + value + '"].variation'), 1542 type = $item.attr('data-type'), 1543 text, 1544 content, 1545 $wrapper, 1546 label; 1547 1548 $item.attr('data-stock', _stock_info[status]); 1549 1550 switch (type) { 1551 case 'option': 1552 text = ' (' + note + ')'; 1553 content = $item.data('content');
1554 $wrapper = $('<div />'); 1555 1556 $wrapper.append(content); 1557 $wrapper 1558 .find('.badge-not-available') 1559 .remove(); 1560 1561 label = $('<span />') 1562 .addClass('badge badge-danger badge-not-available') 1563 .text(' '+note); 1564 1565 $wrapper.append(label); 1566 1567 $item.data('content', $wrapper.html()) 1568 .attr('data-content', $wrapper.html()); 1569 1570 $item.closest('select') 1571 .selectpicker('refresh'); 1572 break; 1573 case 'radio': 1574 $item.find('.badge-not-available') 1575 .remove(); 1576 1577 label = $('<span />') 1578 .addClass('badge badge-danger badge-not-available') 1579 .text(' '+note); 1580 1581 $item.append(label); 1582 break; 1583 case 'swatch': 1584 if (!$item.hasClass('gall-preview')) { 1585 $item.tooltip({ 1586 title: note, 1587 trigger: 'hover', 1588 container: 'body' 1589 }); 1590 } 1591 if (notExists) { 1592 $item.addClass('swatches-not-in-stock'); 1593 } else { 1594 $item.addClass('swatches-sold-out'); 1595 } 1596 break; 1597 } 1598 }, 1599 1600 variationSwitch: function($item, animation, wrapper) { 1601 if ($item) { 1602 var formID = $item.closest('form').attr('id'), 1603 $current = this.getCurrent($item), 1604 key = $current.data('key'), 1605 value = $current.data('value'), 1606 io = $.evo.io(), 1607 args = io.getFormValues(formID), 1608 layout = $('#product-list-type').val(), 1609 $wrapper = this.getWrapper(wrapper); 1610 1611 if (animation) { 1612 $.evo.extended().startSpinner(); 1613 } else { 1614 $('.updatingStockInfo', $wrapper).show(); 1615 } 1616 1617 $('.tooltip.show').remove(); 1618 args.wrapper = wrapper; 1619 args.layout = layout; 1620 1621 $.evo.article() 1622 .variationDispose(wrapper); 1623 1624 io.call('checkVarkombiDependencies', [args, key, value], $item, function (error, data) { 1625 if (animation) { 1626 $.evo.extended().stopSpinner(); 1627 } 1628 $('.updatingStockInfo', $wrapper).hide(); 1629 if (error) { 1630 $.evo.error('checkVarkombiDependencies'); 1631 } 1632 }); 1633 } 1634 }, 1635 1636 modalArticleDetail: function(item, wrapper) 1637 { 1638 let $item = $(item); 1639 let title = $item.data('title'); 1640 let url = $item.data('src'); 1641 1642 if (typeof this.modalView === 'undefined' || this.modalView === null) { 1643 this.modalView = $( 1644 '<div id="' + this.options.modal.id + '" class="modal fade" role="dialog" tabindex="-1" >' + 1645 ' <div class="modal-dialog modal-lg">' + 1646 ' <div class="modal-content">' + 1647 ' <div class="modal-header">' + 1648 ' <button type="button" class="x close" data-dismiss="modal"><i class="fa fa-times"></i></button>' + 1649 ' <div class="modal-title h4">' + title + '</div>' + 1650 ' </div>' + 1651 ' <div class="modal-body">' + 1652 ' <div id="' + wrapper.slice(1) + '" style="min-height:100px">' + 1653 '<div class="jtl-spinner"><i class="fa fa-spinner fa-pulse"></i></div>' + 1654 ' </div>' + 1655 ' </div>' + 1656 ' </div>' + 1657 ' </div>' + 1658 '</div>'); 1659 this.modalView 1660 .on('hidden.bs.modal', () => { 1661 $('.modal-body', this.modalView) 1662 .html('<div id="' + wrapper.slice(1) + '" style="min-height:100px" />'); 1663 $('.modal-title', this.modalView).html(''); 1664 this.modalView 1665 .off('shown.bs.modal'); 1666 this.modalShown = false;
1667 }); 1668 } else { 1669 $('.modal-title', this.modalView).html(title); 1670 $('.modal-body', this.modalView) 1671 .html('<div id="' + wrapper.slice(1) + '" style="min-height:100px">' + 1672 '<div class="jtl-spinner"><i class="fa fa-spinner fa-pulse"></i></div></div>'); 1673 } 1674 1675 this.modalView 1676 .on('shown.bs.modal', () => { 1677 this.modalShown = true; 1678 this.loadModalArticle(url, wrapper, 1679 function() { 1680 // no functionality needed in quickview 1681 // var article = new ArticleClass(); 1682 // article.register(wrapper); 1683 $.evo.extended().stopSpinner(); 1684 $('[data-toggle="popover"]', wrapper).popover({ html: true }); 1685 $('.product-image', wrapper).css('cursor', 'default'); 1686 }, 1687 function() { 1688 $.evo.extended().stopSpinner(); 1689 $.evo.error('Error loading ' + params.url); 1690 } 1691 ); 1692 }) 1693 .modal('show'); 1694 }, 1695 1696 variationPrice: function($item, animation, wrapper) { 1697 var formID = $item.closest('form').attr('id'), 1698 $wrapper = this.getWrapper(wrapper), 1699 io = $.evo.io(), 1700 args = io.getFormValues(formID); 1701 1702 if (animation) { 1703 $.evo.extended().startSpinner($wrapper); 1704 } 1705 1706 args.wrapper = wrapper; 1707 io.call('checkDependencies', [args], $(this), function (error, data) { 1708 let $action = $('button[data-product-id-wl="' + data.response.itemID + '"]'); 1709 if (data.response.check > 0) { 1710 $action.attr('data-wl-pos', data.response.check); 1711 $action.data('wl-pos', data.response.check); 1712 $action.closest('form').find('input[name="wlPos"]').val(data.response.check) 1713 $action.addClass('on-list'); 1714 } else { 1715 $action.removeClass('on-list'); 1716 } 1717 1718 if (animation) { 1719 $.evo.extended().stopSpinner(); 1720 } 1721 if (error) { 1722 $.evo.error('checkDependencies'); 1723 } 1724 }); 1725 }, 1726 1727 variationDispose: function(wrapper) { 1728 var $wrapper = this.getWrapper(wrapper); 1729 1730 $('[role="tooltip"]', $wrapper).remove(); 1731 }, 1732 1733 moveItemAnimation: function(item, moveTo) { 1734 if (!item.length || !moveTo.length || $(this).hasClass('on-list')) { 1735 return; 1736 } 1737 setTimeout(function() { 1738 let itemClone = item.clone() 1739 .offset({ 1740 top: item.offset().top, 1741 left: item.offset().left 1742 }).css({ 1743 'opacity': '0.5', 1744 'position': 'absolute', 1745 'z-index': '10000' 1746 }) 1747 .appendTo($('body')) 1748 .animate({ 1749 'top': moveTo.offset().top + 5, 1750 'left': moveTo.offset().left + 5, 1751 }, 700); 1752 1753 itemClone.animate({ 1754 'width': 0, 1755 'height': 0 1756 }, function () { 1757 $(this).detach() 1758 }); 1759 }, 0); 1760 }, 1761 1762 initAbnahmeIntervallError: function() { 1763 let $intervallNotice = $('#intervall-notice'); 1764 if ($intervallNotice.length > 0) { 1765 $('#quantity').on('change', function () { 1766 let $step = $(this).attr('step'), 1767 diff = Math.abs(($(this).val() % $step) - $step), 1768 epsilon = 0.00000001; 1769 $('#intervall-notice-danger').remove(); 1770 if (!(diff < epsilon || diff + epsilon > $step)) { 1771 $('#quantity-grp').after('<div id="intervall-notice-danger" class="alert alert-danger mt-2">' 1772 + $intervallNotice.html() + '</div>'); 1773 } 1774 }); 1775 } 1776 } 1777 }; 1778 1779 $v = new ArticleClass(); 1780 1781 $(document).ready(function () { 1782 $v.onLoad(); 1783 $v.register(); 1784 }); 1785 1786 $(window).on('resize', 1787 viewport.changed(function(){ 1788 $v.configurator(); 1789 }) 1790 ); 1791 1792 // PLUGIN DEFINITION 1793 // ================= 1794 $.evo.article = function () { 1795 return $v; 1796 }; 1797})(jQuery, document, window, ResponsiveBootstrapToolkit);
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.