1'use strict'; 2 3$('body').on('click', '.option li', function (e) { 4 var i = $(this).parents('.select').attr('id'), 5 v = $(this).children().text(), 6 o = $(this).attr('id'); 7 $('#' + i + ' .selected').attr('id', o).text(v); 8}); 9 10// prevent multiple form submit on client side 11$('.submit_once').closest('form').on('submit', function() { 12 $(this).find('.submit_once').prop('disabled', 'true'); 13 return true; 14}); 15 16/** 17 * Format file size 18 */ 19function formatSize(size) { 20 var fileSize = Math.round(size / 1024), 21 suffix = 'KB', 22 fileSizeParts; 23 24 if (fileSize > 1000) { 25 fileSize = Math.round(fileSize / 1000); 26 suffix = 'MB'; 27 } 28 29 fileSizeParts = fileSize.toString().split('.'); 30 fileSize = fileSizeParts[0]; 31 32 if (fileSizeParts.length > 1) { 33 fileSize += '.' + fileSizeParts[1].substr(0, 2); 34 } 35 fileSize += suffix; 36 37 return fileSize; 38} 39 40function getCategoryMenu(categoryId, success) { 41 var xx = {}; 42 var io = $.evo.io(); 43 44 io.call('getCategoryMenu', [categoryId], xx, function (error, data) { 45 if (error) { 46 console.error(data); 47 } else if (typeof success === 'function') { 48 success(xx.response); 49 } 50 }); 51 52 return true; 53} 54 55function categoryMenu(rootcategory) { 56 if (typeof rootcategory === 'undefined') { 57 rootcategory = $('.sidebar-offcanvas .navbar-categories').html(); 58 } 59 60 $('.sidebar-offcanvas li a.nav-sub').on('click', function(e) { 61 var navbar = $('.sidebar-offcanvas .navbar-categories'), 62 ref = $(this).data('ref'); 63 64 if (ref === 0) { 65 $(navbar).html(rootcategory); 66 categoryMenu(rootcategory); 67 } 68 else { 69 getCategoryMenu(ref, function(data) { 70 $(navbar).html(data); 71 categoryMenu(rootcategory); 72 }); 73 } 74 75 return false; 76 }); 77} 78 79function compatibility() { 80 var __enforceFocus = $.fn.modal.Constructor.prototype.enforceFocus; 81 $.fn.modal.Constructor.prototype.enforceFocus = function () { 82 if ($('.modal-body .g-recaptcha').length === 0) { 83 __enforceFocus.apply(this, arguments); 84 } 85 }; 86} 87function regionsToState(){ 88 $('.js-country-select').on('change', function() { 89 90 var result = {}; 91 var io = $.evo.io(); 92 var country = $(this).find(':selected').val(); 93 country = (country !== null && country !== undefined) ? country : ''; 94 var connection_id = $(this).attr('id').toString().replace("-country",""); 95 96 io.call('getRegionsByCountry', [country], result, function (error, data) { 97 if (error) { 98 console.error(data); 99 } else { 100 var state_id = connection_id+'-state'; 101 var state = $('#'+state_id); 102 var state_data = state.data(); 103 104 if (typeof(result.response) === 'undefined' || state.length === 0) { 105 return; 106 } 107 var title = state_data.defaultoption; 108 var stateIsRequired = result.response.required; 109 var data = result.response.states; 110 var def = $('#'+state_id).val(); 111 if(typeof(data)!=='undefined'){ 112 if (data !== null && data.length > 0) { 113 if (stateIsRequired){ 114 var state = $('<select />').attr({ id: state_id, name: state.attr('name'), class: 'custom-select required form-control js-state-select', required: 'required'}); 115 } else { 116 var state = $('<select />').attr({ id: state_id, name: state.attr('name'), class: 'custom-select form-control js-state-select'}); 117 } 118 119 Object.keys(state_data).forEach(function(key,index) { 120 state.data(key,state_data[key]); 121 }); 122 123 state.append('<option value="">' + title + '</option>'); 124 $(data).each(function(idx, item) { 125 state.append( 126 $('<option></option>').val(item.iso).html(item.name) 127 .attr('selected', item.iso == def || item.name == def ? 'selected' : false) 128 ); 129 }); 130 $('#'+state_id).replaceWith(state); 131 } else { 132 if (stateIsRequired) { 133 var state = $('<input />').attr({ type: 'text', id: state_id, name: state.attr('name'), class: 'required form-control js-state-select', placeholder: title, required: 'required' }); 134 } else { 135 var state = $('<input />').attr({ type: 'text', id: state_id, name: state.attr('name'), class: 'form-control js-state-select', placeholder: title }); 136 }
137 Object.keys(state_data).forEach(function(key,index) { 138 state.data(key,state_data[key]); 139 }); 140 $('#'+state_id).replaceWith(state); 141 } 142 if (stateIsRequired){ 143 state.parent().find('.state-optional').addClass('d-none'); 144 } else { 145 state.parent().find('.state-optional').removeClass('d-none'); 146 } 147 } 148 } 149 }); 150 return false; 151 }).trigger('change'); 152} 153 154function loadContent(url, setCustomAnchorScrolling) 155{ 156 $.evo.extended().loadContent(url, function() { 157 $.evo.extended().register(); 158 159 if (typeof $.evo.article === 'function') { 160 $.evo.article().onLoad(); 161 $.evo.article().register(); 162 addValidationListener(); 163 } 164 165 let topbarHeight = $('#header-top-bar').outerHeight() || 0, 166 wrapperHeight = $('#jtl-nav-wrapper').outerHeight() || 0, 167 productListHeight = $('#product-list').offset().top || 0, 168 pageNavHeight = $('.productlist-page-nav').outerHeight() || 0; 169 170 if (setCustomAnchorScrolling instanceof Function) { 171 setCustomAnchorScrolling(); 172 } 173 174 $('html,body').animate({ 175 scrollTop: productListHeight - wrapperHeight - topbarHeight - pageNavHeight - 20 176 }, 100); 177 }); 178} 179 180function sanitizeOutput(val) { 181 return val.replace(/\&/g, '&') 182 .replace(/\</g, '<') 183 .replace(/\>/g, '>') 184 .replace(/\"/g, '"') 185 .replace(/\'/g, ''') 186 .replace(/\//g, '/'); 187} 188 189function addValidationListener() { 190 var forms = $('form.jtl-validate'), 191 inputs = $('form.jtl-validate input, form.jtl-validate textarea').not('[type="radio"],[type="checkbox"]'), 192 selects = $('form.jtl-validate select'), 193 checkables = $('form.jtl-validate input[type="radio"], form.jtl-validate input[type="checkbox"]'), 194 $body = $('body'); 195 196 for (var i = 0; i < forms.length; i++) { 197 forms[i].addEventListener('invalid', function (event) { 198 event.preventDefault(); 199 $(event.target).closest('.form-group').find('div.form-error-msg').remove(); 200 $(event.target).closest('.form-group') 201 .addClass('has-error') 202 .append('<div class="form-error-msg w-100">' + sanitizeOutput(event.target.validationMessage) + '</div>'); 203 204 if (!$body.data('doScrolling')) { 205 var $firstError = $(event.target).closest('.form-group.has-error'); 206 if ($firstError.length > 0) { 207 $body.data('doScrolling', true); 208 var $nav = $('#jtl-nav-wrapper.sticky-top'), 209 fixedOffset = $nav.length > 0 ? $nav.outerHeight() : 0, 210 vpHeight = $(window).height(), 211 scrollTop = $(window).scrollTop(); 212 if ($firstError.offset().top > (scrollTop + vpHeight) || $firstError.offset().top < scrollTop) { 213 $('html, body').animate( 214 { 215 scrollTop: $firstError.offset().top - fixedOffset - parseInt($firstError.css('margin-top')) 216 }, 217 { 218 done: function () { 219 $body.data('doScrolling', false); 220 } 221 }, 300 222 ); 223 } 224 } 225 } 226 }, true); 227 } 228 229 for (var i = 0; i < inputs.length; i++) { 230 inputs[i].addEventListener('blur', function (event) { 231 checkInputError(event); 232 }, true); 233 } 234 for (var i = 0; i < checkables.length; i++) { 235 checkables[i].addEventListener('click', function (event) { 236 checkInputError(event); 237 }, true); 238 } 239 for (var i = 0; i < selects.length; i++) { 240 selects[i].addEventListener('change', function (event) { 241 checkInputError(event); 242 }, true); 243 } 244} 245 246const customAnchorScrollingListener = function customAnchorScrollingListener(event) { 247 event.preventDefault(); 248 const href = event.target.getAttribute('href'); 249 if (href === null) { 250 return false;
251 } 252 253 let targetID = href.replace(/^#/, ''); 254 if (targetID === '') { 255 return false; 256 } 257 258 const scrollTo = document.getElementById(targetID); 259 if (scrollTo) { 260 if (scrollTo.scrollIntoView) { 261 scrollTo.scrollIntoView({ behavior: 'smooth' }); 262 } else { 263 let rect = scrollTo.getBoundingClientRect(); 264 window.scrollTo(rect.x, rect.y); 265 } 266 } 267}; 268 269const setCustomAnchorScrolling = function setCustomAnchorScrolling() { 270 const links = Array.prototype.slice.call( 271 document.querySelectorAll('a'), 272 0 273 ); 274 links.filter(el => (el.getAttribute('href') || '').match(/^#/)).forEach(el => { 275 let targetID = el.getAttribute('href').replace(/^#/, ''); 276 if (targetID === '') { 277 return false; 278 } 279 280 const scrollTo = document.getElementById(targetID); 281 if (scrollTo) { 282 el.removeEventListener('click', customAnchorScrollingListener); 283 el.addEventListener('click', customAnchorScrollingListener); 284 } 285 }); 286}; 287 288function checkInputError(event) 289{ 290 var $target = $(event.target); 291 if ($target.parents('.cfg-group') != undefined) { 292 $target.parents('.cfg-group').find('div.form-error-msg').remove(); 293 } 294 $target.parents('.form-group').find('div.form-error-msg').remove(); 295 296 if ($target.data('must-equal-to') !== undefined) { 297 var $equalsTo = $($target.data('must-equal-to')); 298 if ($equalsTo.length === 1) { 299 var theOther = $equalsTo[0]; 300 if (theOther.value !== '' && theOther.value !== event.target.value && event.target.value !== '') { 301 event.target.setCustomValidity($target.data('custom-message') !== undefined ? $target.data('custom-message') : sanitizeOutput(event.target.validationMessage)); 302 } else { 303 event.target.setCustomValidity(''); 304 } 305 } 306 } 307 308 if (event.target.validity.valid) { 309 $target.closest('.form-group').removeClass('has-error'); 310 } else { 311 $target.closest('.form-group').addClass('has-error').append('<div class="form-error-msg">' + sanitizeOutput(event.target.validationMessage) + '</div>'); 312 } 313} 314 315function captcha_filled() { 316 $('.g-recaptcha').closest('.form-group').find('div.form-error-msg').remove(); 317} 318 319function isTouchCapable() { 320 return 'ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch); 321} 322 323function initWow() 324{ 325 //CUSTOM new WOW().init(); 326} 327/* 328$(window).load(function(){ 329 navigation(); 330});*/ 331 332$(document).ready(function () { 333 $('.collapse-non-validate') 334 .on('hidden.bs.collapse', function(e) { 335 $(e.target) 336 .addClass('hidden') 337 .find('fieldset, .form-control') 338 .attr('disabled', true); 339 e.stopPropagation(); 340 }) 341 .on('show.bs.collapse', function(e) { 342 $(e.target) 343 .removeClass('hidden') 344 .attr('disabled', false); 345 e.stopPropagation(); 346 }).on('shown.bs.collapse', function(e) { 347 $(e.target) 348 .find('fieldset, .form-control') 349 .filter(function (i, e) { 350 return $(e).closest('.collapse-non-validate.collapse').hasClass('show'); 351 }) 352 .attr('disabled', false); 353 e.stopPropagation(); 354 }); 355 $('.collapse-non-validate.collapse.show') 356 .removeClass('hidden') 357 .find('fieldset, .form-control') 358 .attr('disabled', false); 359 $('.collapse-non-validate.collapse:not(.show)') 360 .addClass('hidden') 361 .find('fieldset, .form-control') 362 .attr('disabled', true); 363 364 $('.collapse.collapse-with-button') 365 .on('show.bs.collapse', function (e) { 366 let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]'); 367 btn.html(btn.data('labelHide')); 368 }) 369 .on('hidden.bs.collapse', function (e) { 370 let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]'); 371 btn.html(btn.data('labelShow')); 372 }); 373 $('.collapse.collapse-with-clip') 374 .on('shown.bs.collapse', function (e) { 375 $('#clip-text-' + $(e.target).attr("id")).hide(); 376 }) 377 .on('hide.bs.collapse', function (e) { 378 $('#clip-text-' + $(e.target).attr("id")).show(); 379 }); 380 381 $('#complete-order-button').on('click', function () { 382 var commentField = $('#comment'), 383 commentFieldHidden = $('#comment-hidden'); 384 if (commentField && commentFieldHidden) { 385 commentFieldHidden.val(commentField.val()); 386 } 387 }); 388 389 $(document).on('click', '.footnote-vat a, .versand, .popup', function(e) { 390 let url = e.currentTarget.href, 391 classes = $(this).data('modal-classes') || ''; 392 url += (url.indexOf('?') === -1) ? '?isAjax=true' : '&isAjax=true';
393 eModal.ajax({ 394 size: 'xl ' + classes, 395 url: url, 396 title: typeof e.currentTarget.title !== 'undefined' ? e.currentTarget.title : '', 397 keyboard: true, 398 tabindex: -1, 399 buttons: false 400 }); 401 e.stopPropagation(); 402 return false; 403 }); 404 405 $(document).on('click', '.pagination-ajax a:not(.active), .js-pagination-ajax:not(.active)', function(e) { 406 let url = $(this).attr('href'); 407 history.pushState(null, null, url); 408 loadContent(url, setCustomAnchorScrolling); 409 return e.preventDefault(); 410 }); 411 412 if ($('.js-pagination-ajax').length > 0) { 413 window.addEventListener('popstate', () => { 414 loadContent(document.location.href, setCustomAnchorScrolling); 415 }, false); 416 } 417 418 setCustomAnchorScrolling(); 419 420 $('.dropdown .dropdown-menu.keepopen').on('click touchstart', function(e) { 421 e.stopPropagation(); 422 },{passive: true}); 423 424 if (typeof $.fn.jtl_search === 'undefined') { 425 var productSearch = new Bloodhound({ 426 datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'), 427 queryTokenizer: Bloodhound.tokenizers.whitespace, 428 remote: { 429 url: $.evo.io().options.ioUrl + '?io={"name":"suggestions", "params":["%QUERY"]}', 430 wildcard: '%QUERY' 431 } 432 }); 433 434 let $searchInput = $('input[name="qs"]'); 435 $searchInput.typeahead( 436 { 437 highlight: true 438 }, 439 { 440 name: 'product-search', 441 display: 'keyword', 442 source: productSearch, 443 templates: { 444 suggestion: function (e) { 445 return e.suggestion; 446 } 447 } 448 } 449 ); 450 $searchInput.on('keydown keyup blur', function () { 451 if ($(this).val().length === 0) { 452 $(this).closest('form').find('.form-clear').addClass('d-none'); 453 } else { 454 $(this).closest('form').find('.form-clear').removeClass('d-none'); 455 } 456 }); 457 $('.search-wrapper .form-clear').on('click', function() { 458 $searchInput.typeahead('val', ''); 459 $(this).addClass('d-none'); 460 }); 461 } 462 463 var citySuggestion = new Bloodhound({ 464 datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'), 465 queryTokenizer: Bloodhound.tokenizers.whitespace, 466 remote: { 467 url: $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).closest('fieldset').find('.country-input').val() + '", "' + $(this).closest('fieldset').find('.postcode_input').val() + '"]}', 468 wildcard: '%QUERY' 469 }, 470 dataType: "json" 471 }); 472 $('.city_input').on('focusin', function () { 473 citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).closest('fieldset').find('.country-input').val() + '", "' + $(this).closest('fieldset').find('.postcode_input').val() + '"]}'; 474 }); 475 $('.postcode_input').on('change', function () { 476 citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).closest('fieldset').find('.country-input').val() + '", "' + $(this).val() + '"]}'; 477 }); 478 $('.country_input').on('change', function () { 479 citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).val() + '", "' + $(this).closest('fieldset').find('.postcode_input').val() + '"]}'; 480 }); 481 482 $('.city_input').typeahead( 483 { 484 hint: true, 485 minLength: 0 486 }, 487 { 488 limit: 50, 489 name: 'cities', 490 source: citySuggestion 491 } 492 ); 493 494 $('.btn-offcanvas').on('click', function() { 495 $('body').trigger('click'); 496 }); 497 498 if ("ontouchstart" in document.documentElement) { 499 $('.variations .swatches .variation').on('mouseover', function() { 500 $(this).trigger('click'); 501 }); 502 } 503 504 /* 505 * show subcategory on caret click 506 */ 507 $('section.box-categories .nav-panel li a').on('click', function(e) { 508 if ($(e.target).hasClass("nav-toggle")) { 509 $(e.delegateTarget) 510 .parent('li') 511 .find('> ul.nav').toggle(); 512 return false;
513 } 514 }); 515 516 /* 517 * show linkgroup on caret click 518 */ 519 $('section.box-linkgroup .nav-panel li a').on('click', function(e) { 520 if ($(e.target).hasClass("nav-toggle")) { 521 $(e.delegateTarget) 522 .parent('li') 523 .find('> ul.nav').toggle(); 524 return false; 525 } 526 }); 527 528 /* 529 * Banner 530 */ 531 var bannerLink = $('.banner > a:not(.empty-popover)'); 532 bannerLink.popover({ 533 html: true, 534 placement: 'bottom', 535 trigger: 'hover', 536 container: 'body', 537 sanitize: false, 538 template: '<div class="popover popover-min-width" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>', 539 content: function () { 540 return $(this).children('.area-desc').html() 541 } 542 }); 543 544 bannerLink.on('mouseenter', function () { 545 $(this).animate({ 546 borderWidth: 2, 547 opacity: 0.5 548 }, 300); 549 }); 550 551 bannerLink.on('mouseleave', function () { 552 $(this).animate({ 553 borderWidth: 0, 554 opacity: 1 555 }, 300); 556 }); 557 558 $('.banner').on('mouseenter', function () { 559 $(this).children('a').animate({ 560 borderWidth: 8, 561 opacity: 0 562 }, 900, function () { 563 $(this).css({opacity: 1, borderWidth: 0}); 564 }); 565 }); 566 567 $('.banner > a[href=""]').on('click', function () { 568 return false; 569 }); 570 571 /* 572 * alert actions 573 */ 574 $('.alert .close').on('click', function (){ 575 $(this).parent().fadeOut(1000); 576 }); 577 578 $('.alert').each(function(){ 579 if ($(this).data('fade-out') > 0) { 580 $(this).fadeOut($(this).data('fade-out')); 581 } 582 }); 583 584 /* 585 * margin to last filter-box 586 */ 587 $('aside .box[class*=box-filter-]').last().addClass('mb-5'); 588 589 /* 590 * set bootstrap viewport 591 */ 592 (function($, document, window, viewport){ 593 var $body = $('body'); 594 595 $(window).on('resize', 596 viewport.changed(function() { 597 $body.attr('data-viewport', viewport.current()); 598 }) 599 ); 600 $body.attr('data-viewport', viewport.current()); 601 $body.attr('data-touchcapable', isTouchCapable() ? 'true' : 'false'); 602 })(jQuery, document, window, ResponsiveBootstrapToolkit); 603 604 605 $('.onchangeSubmit').on('change', function(){ 606 this.form.submit(); 607 }); 608 609 $('#mobile-search-dropdown').on('click', function() { 610 setTimeout(function(){ 611 $('#search-header-desktop').focus(); 612 },100); 613 }); 614 615 categoryMenu(); 616 regionsToState(); 617 compatibility(); 618 addValidationListener(); 619 initWow(); 620 setClickableRow(); 621 622 document.addEventListener('lazybeforesizes', function(e){ 623 //use width of parent node instead of the image width itself 624 var parent = e.target.parentNode; 625 626 if(parent.nodeName == 'PICTURE'){ 627 parent = parent.parentNode; 628 } 629 e.detail.width = parent.offsetWidth || e.detail.width; 630 }); 631 632 // init auto expand for textareas 633 $('textarea.auto-expand').on('input click', function (event) { 634 autoExpand(event.target); 635 }); 636 637 $('input[maxlength][data-chars-left-msg]').on('input', function (event) { 638 let maxLength = $(this).attr('maxlength'), 639 limit = .1 * maxLength, 640 remaining = maxLength - $(this).val().length; 641 642 $(this).closest('.form-group').find('.char-left').remove(); 643 644 if (remaining <= limit) { 645 $(this).closest('.form-group').append( 646 '<div class="text-warning char-left"><b>' + remaining + '</b> ' + $(this).data('chars-left-msg') + '</div>' 647 ); 648 } 649 }); 650}); 651 652function setClickableRow() 653{ 654 $('.clickable-row').off().on('click', function() { 655 window.location = $(this).data('href'); 656 }); 657} 658 659function isMobileByBodyClass() { 660 return $('body').hasClass('is-mobile'); 661} 662 663function autoExpand(field) { 664 field.style.height = 'inherit'; 665
666 let computed = window.getComputedStyle(field), 667 height = parseInt(computed.getPropertyValue('border-top-width'), 10) 668 + parseInt(computed.getPropertyValue('padding-top'), 10) 669 + field.scrollHeight 670 + parseInt(computed.getPropertyValue('padding-bottom'), 10) 671 + parseInt(computed.getPropertyValue('border-bottom-width'), 10); 672 673 field.style.height = height + 'px'; 674}
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.