PageSourceSearch

https://www.under-the-cork.de/templates/easyTemplate360/js/global.js?v=0.2.2

js under-the-cork.de collected 2026-10-08 16:43:17 UTC 21,415 bytes, 605 lines download raw bytes

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, '&amp;')
178        .replace(/\</g, '&lt;')
179        .replace(/\>/g, '&gt;')
180        .replace(/\"/g, '&quot;')
181        .replace(/\'/g, '&#x27;')
182        .replace(/\//g, '&#x2F;');
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.