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