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) 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 $('html,body').animate({ 170 scrollTop: productListHeight - wrapperHeight - topbarHeight - pageNavHeight - 20 171 }, 100); 172 }); 173} 174 175function sanitizeOutput(val) { 176 return val.replace(/\&/g, '&') 177 .replace(/\</g, '<') 178 .replace(/\>/g, '>') 179 .replace(/\"/g, '"') 180 .replace(/\'/g, ''') 181 .replace(/\//g, '/'); 182} 183 184function addValidationListener() { 185 var forms = $('form.jtl-validate'), 186 inputs = $('form.jtl-validate input, form.jtl-validate textarea').not('[type="radio"],[type="checkbox"]'), 187 selects = $('form.jtl-validate select'), 188 checkables = $('form.jtl-validate input[type="radio"], form.jtl-validate input[type="checkbox"]'), 189 $body = $('body'); 190 191 for (var i = 0; i < forms.length; i++) { 192 forms[i].addEventListener('invalid', function (event) { 193 event.preventDefault(); 194 $(event.target).closest('.form-group').find('div.form-error-msg').remove(); 195 $(event.target).closest('.form-group') 196 .addClass('has-error') 197 .append('<div class="form-error-msg w-100">' + sanitizeOutput(event.target.validationMessage) + '</div>'); 198 199 if (!$body.data('doScrolling')) { 200 var $firstError = $(event.target).closest('.form-group.has-error'); 201 if ($firstError.length > 0) { 202 $body.data('doScrolling', true); 203 var $nav = $('#jtl-nav-wrapper.sticky-top'), 204 fixedOffset = $nav.length > 0 ? $nav.outerHeight() : 0, 205 vpHeight = $(window).height(), 206 scrollTop = $(window).scrollTop(); 207 if ($firstError.offset().top > (scrollTop + vpHeight) || $firstError.offset().top < scrollTop) { 208 $('html, body').animate( 209 { 210 scrollTop: $firstError.offset().top - fixedOffset - parseInt($firstError.css('margin-top')) 211 }, 212 { 213 done: function () { 214 $body.data('doScrolling', false); 215 } 216 }, 300 217 ); 218 } 219 } 220 } 221 }, true); 222 } 223 224 for (var i = 0; i < inputs.length; i++) { 225 inputs[i].addEventListener('blur', function (event) { 226 checkInputError(event); 227 }, true); 228 } 229 for (var i = 0; i < checkables.length; i++) { 230 checkables[i].addEventListener('click', function (event) { 231 checkInputError(event); 232 }, true); 233 } 234 for (var i = 0; i < selects.length; i++) { 235 selects[i].addEventListener('change', function (event) { 236 checkInputError(event); 237 }, true); 238 } 239} 240 241function checkInputError(event) 242{ 243 var $target = $(event.target); 244 if ($target.parents('.cfg-group') != undefined) { 245 $target.parents('.cfg-group').find('div.form-error-msg').remove(); 246 } 247 $target.parents('.form-group').find('div.form-error-msg').remove(); 248 249 if ($target.data('must-equal-to') !== undefined) { 250 var $equalsTo = $($target.data('must-equal-to')); 251 if ($equalsTo.length === 1) { 252 var theOther = $equalsTo[0]; 253 if (theOther.value !== '' && theOther.value !== event.target.value && event.target.value !== '') { 254 event.target.setCustomValidity($target.data('custom-message') !== undefined ? $target.data('custom-message') : sanitizeOutput(event.target.validationMessage)); 255 } else { 256 event.target.setCustomValidity(''); 257 } 258 } 259 } 260 261 if (event.target.validity.valid) { 262 $target.closest('.form-group').removeClass('has-error'); 263 } else { 264 $target.closest('.form-group').addClass('has-error').append('<div class="form-error-msg">' + sanitizeOutput(event.target.validationMessage) + '</div>'); 265 } 266} 267 268function captcha_filled() { 269 $('.g-recaptcha').closest('.form-group').find('div.form-error-msg').remove(); 270} 271 272function isTouchCapable() { 273 return 'ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch); 274} 275 276function initWow() 277{ 278 new WOW().init(); 279} 280/* 281$(window).load(function(){ 282 navigation(); 283});*/ 284 285$(document).ready(function () { 286 $('.collapse-non-validate') 287 .on('hidden.bs.collapse', function(e) { 288 $(e.target) 289 .addClass('hidden') 290 .find('fieldset, .form-control') 291 .attr('disabled', true); 292 e.stopPropagation(); 293 }) 294 .on('show.bs.collapse', function(e) { 295 $(e.target) 296 .removeClass('hidden') 297 .attr('disabled', false); 298 e.stopPropagation(); 299 }).on('shown.bs.collapse', function(e) { 300 $(e.target) 301 .find('fieldset, .form-control') 302 .filter(function (i, e) { 303 return $(e).closest('.collapse-non-validate.collapse').hasClass('show'); 304 }) 305 .attr('disabled', false); 306 e.stopPropagation(); 307 }); 308 $('.collapse-non-validate.collapse.show') 309 .removeClass('hidden') 310 .find('fieldset, .form-control') 311 .attr('disabled', false); 312 $('.collapse-non-validate.collapse:not(.show)') 313 .addClass('hidden') 314 .find('fieldset, .form-control') 315 .attr('disabled', true); 316 317 $('.collapse.collapse-with-button') 318 .on('show.bs.collapse', function (e) { 319 let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]'); 320 btn.html(btn.data('labelHide')); 321 }) 322 .on('hidden.bs.collapse', function (e) { 323 let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]'); 324 btn.html(btn.data('labelShow')); 325 }); 326 $('.collapse.collapse-with-clip') 327 .on('shown.bs.collapse', function (e) { 328 $('#clip-text-' + $(e.target).attr("id")).hide(); 329 }) 330 .on('hide.bs.collapse', function (e) { 331 $('#clip-text-' + $(e.target).attr("id")).show(); 332 }); 333 334 $('#complete-order-button').on('click', function () { 335 var commentField = $('#comment'), 336 commentFieldHidden = $('#comment-hidden'); 337 if (commentField && commentFieldHidden) { 338 commentFieldHidden.val(commentField.val()); 339 } 340 }); 341 342 $(document).on('click', '.footnote-vat a, .versand, .popup', function(e) { 343 let url = e.currentTarget.href, 344 classes = $(this).data('modal-classes') || ''; 345 url += (url.indexOf('?') === -1) ? '?isAjax=true' : '&isAjax=true';
346 eModal.ajax({ 347 size: 'xl ' + classes, 348 url: url, 349 title: typeof e.currentTarget.title !== 'undefined' ? e.currentTarget.title : '', 350 keyboard: true, 351 tabindex: -1, 352 buttons: false 353 }); 354 e.stopPropagation(); 355 return false; 356 }); 357 358 $(document).on('click', '.pagination-ajax a:not(.active), .js-pagination-ajax:not(.active)', function(e) { 359 var url = $(this).attr('href'); 360 history.pushState(null, null, url); 361 loadContent(url); 362 return e.preventDefault(); 363 }); 364 365 if ($('.js-pagination-ajax').length > 0) { 366 window.addEventListener('popstate', function(e) { 367 loadContent(document.location.href); 368 }, false); 369 } 370 371 $('.dropdown .dropdown-menu.keepopen').on('click touchstart', function(e) { 372 e.stopPropagation(); 373 },{passive: true}); 374 375 if (typeof $.fn.jtl_search === 'undefined') { 376 var productSearch = new Bloodhound({ 377 datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'), 378 queryTokenizer: Bloodhound.tokenizers.whitespace, 379 remote: { 380 url: $.evo.io().options.ioUrl + '?io={"name":"suggestions", "params":["%QUERY"]}', 381 wildcard: '%QUERY' 382 } 383 }); 384 385 let $searchInput = $('input[name="qs"]'); 386 $searchInput.typeahead( 387 { 388 highlight: true 389 }, 390 { 391 name: 'product-search', 392 display: 'keyword', 393 source: productSearch, 394 templates: { 395 suggestion: function (e) { 396 return e.suggestion; 397 } 398 } 399 } 400 ); 401 $searchInput.on('keydown keyup blur', function () { 402 if ($(this).val().length === 0) { 403 $(this).closest('form').find('.form-clear').addClass('d-none'); 404 } else { 405 $(this).closest('form').find('.form-clear').removeClass('d-none'); 406 } 407 }); 408 $('.search-wrapper .form-clear').on('click', function() { 409 $searchInput.typeahead('val', ''); 410 $(this).addClass('d-none'); 411 }); 412 } 413 414 var citySuggestion = new Bloodhound({ 415 datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'), 416 queryTokenizer: Bloodhound.tokenizers.whitespace, 417 remote: { 418 url: $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).closest('fieldset').find('.country-input').val() + '", "' + $(this).closest('fieldset').find('.postcode_input').val() + '"]}', 419 wildcard: '%QUERY' 420 }, 421 dataType: "json" 422 }); 423 $('.city_input').on('focusin', function () { 424 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() + '"]}'; 425 }); 426 $('.postcode_input').on('change', function () { 427 citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).closest('fieldset').find('.country-input').val() + '", "' + $(this).val() + '"]}'; 428 }); 429 $('.country_input').on('change', function () { 430 citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "' + $(this).val() + '", "' + $(this).closest('fieldset').find('.postcode_input').val() + '"]}'; 431 }); 432 433 $('.city_input').typeahead( 434 { 435 hint: true, 436 minLength: 0 437 }, 438 { 439 limit: 50, 440 name: 'cities', 441 source: citySuggestion 442 } 443 ); 444 445 $('.btn-offcanvas').on('click', function() { 446 $('body').trigger('click'); 447 }); 448 449 if ("ontouchstart" in document.documentElement) { 450 $('.variations .swatches .variation').on('mouseover', function() { 451 $(this).trigger('click'); 452 }); 453 } 454 455 /* 456 * show subcategory on caret click 457 */ 458 $('section.box-categories .nav-panel li a').on('click', function(e) { 459 if ($(e.target).hasClass("nav-toggle")) { 460 $(e.delegateTarget) 461 .parent('li') 462 .find('> ul.nav').toggle(); 463 return false;
464 } 465 }); 466 467 /* 468 * show linkgroup on caret click 469 */ 470 $('section.box-linkgroup .nav-panel li a').on('click', function(e) { 471 if ($(e.target).hasClass("nav-toggle")) { 472 $(e.delegateTarget) 473 .parent('li') 474 .find('> ul.nav').toggle(); 475 return false; 476 } 477 }); 478 479 /* 480 * Banner 481 */ 482 var bannerLink = $('.banner > a:not(.empty-popover)'); 483 bannerLink.popover({ 484 html: true, 485 placement: 'bottom', 486 trigger: 'hover', 487 container: 'body', 488 sanitize: false, 489 template: '<div class="popover popover-min-width" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>', 490 content: function () { 491 return $(this).children('.area-desc').html() 492 } 493 }); 494 495 bannerLink.on('mouseenter', function () { 496 $(this).animate({ 497 borderWidth: 2, 498 opacity: 0.5 499 }, 300); 500 }); 501 502 bannerLink.on('mouseleave', function () { 503 $(this).animate({ 504 borderWidth: 0, 505 opacity: 1 506 }, 300); 507 }); 508 509 $('.banner').on('mouseenter', function () { 510 $(this).children('a').animate({ 511 borderWidth: 8, 512 opacity: 0 513 }, 900, function () { 514 $(this).css({opacity: 1, borderWidth: 0}); 515 }); 516 }); 517 518 $('.banner > a[href=""]').on('click', function () { 519 return false; 520 }); 521 522 /* 523 * alert actions 524 */ 525 $('.alert .close').on('click', function (){ 526 $(this).parent().fadeOut(1000); 527 }); 528 529 $('.alert').each(function(){ 530 if ($(this).data('fade-out') > 0) { 531 $(this).fadeOut($(this).data('fade-out')); 532 } 533 }); 534 535 /* 536 * margin to last filter-box 537 */ 538 $('aside .box[class*=box-filter-]').last().addClass('mb-5'); 539 540 /* 541 * set bootstrap viewport 542 */ 543 (function($, document, window, viewport){ 544 var $body = $('body'); 545 546 $(window).on('resize', 547 viewport.changed(function() { 548 $body.attr('data-viewport', viewport.current()); 549 }) 550 ); 551 $body.attr('data-viewport', viewport.current()); 552 $body.attr('data-touchcapable', isTouchCapable() ? 'true' : 'false'); 553 })(jQuery, document, window, ResponsiveBootstrapToolkit); 554 555 556 $('.onchangeSubmit').on('change', function(){ 557 this.form.submit(); 558 }); 559 560 $('#mobile-search-dropdown').on('click', function() { 561 setTimeout(function(){ 562 $('#search-header-desktop').focus(); 563 },100); 564 }); 565 566 categoryMenu(); 567 regionsToState(); 568 compatibility(); 569 addValidationListener(); 570 initWow(); 571 setClickableRow(); 572 573 document.addEventListener('lazybeforesizes', function(e){ 574 //use width of parent node instead of the image width itself 575 var parent = e.target.parentNode; 576 577 if(parent.nodeName == 'PICTURE'){ 578 parent = parent.parentNode; 579 } 580 e.detail.width = parent.offsetWidth || e.detail.width; 581 }); 582 583 // init auto expand for textareas 584 $('textarea.auto-expand').on('input click', function (event) { 585 autoExpand(event.target); 586 }); 587 588 $('input[maxlength][data-chars-left-msg]').on('input', function (event) { 589 let maxLength = $(this).attr('maxlength'), 590 limit = .1 * maxLength, 591 remaining = maxLength - $(this).val().length; 592 593 $(this).closest('.form-group').find('.char-left').remove(); 594 595 if (remaining <= limit) { 596 $(this).closest('.form-group').append( 597 '<div class="text-warning char-left"><b>' + remaining + '</b> ' + $(this).data('chars-left-msg') + '</div>' 598 ); 599 } 600 }); 601}); 602 603function setClickableRow() 604{ 605 $('.clickable-row').off().on('click', function() { 606 window.location = $(this).data('href'); 607 }); 608} 609 610function isMobileByBodyClass() { 611 return $('body').hasClass('is-mobile'); 612} 613 614function autoExpand(field) { 615 field.style.height = 'inherit'; 616
617 let computed = window.getComputedStyle(field), 618 height = parseInt(computed.getPropertyValue('border-top-width'), 10) 619 + parseInt(computed.getPropertyValue('padding-top'), 10) 620 + field.scrollHeight 621 + parseInt(computed.getPropertyValue('padding-bottom'), 10) 622 + parseInt(computed.getPropertyValue('border-bottom-width'), 10); 623 624 field.style.height = height + 'px'; 625}
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.