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