PageSourceSearch

https://www.dj-technik.de/templates/DJTechnik/js/global.js?v=5.4.157

js dj-technik.de collected 2026-10-06 18:34:32 UTC 23,593 bytes, 674 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
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, '&amp;')
182        .replace(/\</g, '&lt;')
183        .replace(/\>/g, '&gt;')
184        .replace(/\"/g, '&quot;')
185        .replace(/\'/g, '&#x27;')
186        .replace(/\//g, '&#x2F;');
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.