PageSourceSearch

https://www.gnz-verlag.de/pub/static/version1789988666/frontend/Vc/vrm/de_DE/Vrm_ExternalLib/js/externallib.js

js gnz-verlag.de collected 2026-10-02 01:52:07 UTC 19,723 bytes, 567 lines download raw bytes

1/*
2 * @category  MSP
3 * @editor    Tommy Köster
4 * @copyright 2026 - MSP Medien Systempartner GmbH & Co. KG
5 * @license   http://www.medien-systempartner.de/  Commercial
6 * @link      www.medien-systempartner.de
7 * @updated   24.06.26, 12:52
8 */
9
10let enableTracking = true;
11
12document.addEventListener('click', clickEvents);
13
14function clickEvents(event) {
15    let element = event.target;
16    if (Vrm.parentHasClass(element, 'faqCatTitleBox')) {
17        element = Vrm.parentHasClass(element, 'faqCatTitleBox');
18        Vc.Externallib.triggerFaqCat(element);
19    }
20    if (Vrm.parentHasClass(element, 'faqTitleBox')) {
21        element = Vrm.parentHasClass(element, 'faqTitleBox');
22        Vc.Externallib.triggerFaq(element);
23    }
24    if (element.id === 'reasons_submit_btn') {
25        let reason = '';
26        let form = document.getElementById('reasons_form');
27        reason = form.querySelector('input[name="lieferendeGrund"]:checked').value;
28        let data = Vrm.Tracking.Functions.selectReason(reason);
29        Vrm.Tracking.Functions.pageViewPush(data);
30    }
31}
32
33Vrm.Tracking = Vrm.Tracking || {};
34Vrm.Tracking.Functions = Vrm.Tracking.Functions || {
35
36    logVirtualPageView: function (data) {
37        if (!data || data.event !== 'VirtualPageView') {
38            return;
39        }
40
41        const now = new Date();
42        const loggingStart = new Date('2026-06-01T00:00:00+02:00');
43        const loggingEnd = new Date('2026-06-08T00:00:00+02:00');
44
45        if (now < loggingStart || now >= loggingEnd) {
46            return;
47        }
48
49        const payload = {
50            timestamp: new Date().toISOString(),
51            timestampLocal: now.toLocaleString('sv-SE', {
52                timeZone: 'Europe/Berlin',
53                year: 'numeric',
54                month: '2-digit',
55                day: '2-digit',
56                hour: '2-digit',
57                minute: '2-digit',
58                second: '2-digit'
59            }),
60            browserTimestamp: Date.now(),
61            pageUrl: window.location.href,
62            referrer: document.referrer,
63            userAgent: navigator.userAgent,
64            data: data
65        };
66
67        let postData = {
68            controller: 'logVirtualPageView',
69            data: payload
70        }
71
72        try {
73            Vrm.ajax(
74                postData,
75                window.location.origin + '/vrmtemplate/ajax/log'
76            ).then(function (response) {
77                console.log('[Tracking Debug] Log response:', response.status, response.statusText);
78                if (!response.ok) {
79                    console.warn('[Tracking Debug] Log request failed with HTTP status:', response.status);
80                }
81            }).catch(function (error) {
82                console.warn('[Tracking Debug] VirtualPageView log failed:', error);
83            });
84        } catch (error) {
85            console.warn('[Tracking Debug] VirtualPageView log could not be sent:', error);
86        }
87    },
88
89    pageViewPush: function (data) {
90        if (enableTracking) {
91            window.dataLayer = window.dataLayer || [];
92            window.dataLayer.push(data);
93        }
94    },
95
96    getVirtualPageData: function (title = '',prevPage = '') {
97        let loginStatus = 'logged_out';
98        if (typeof Vc !== 'undefined' && Vc.isLoggedIn) {
99            loginStatus = 'logged_in';
100        }
101
102        if (title === '') {
103            title = document.title;
104        }
105        if (prevPage === '') {
106            prevPage = document.referrer;
107        }
108        return {
109            'event':'VirtualPageView',
110            'virtualPageURI': window.location.pathname + window.location.search,
111            'virtualPageURL': window.location.href || document.documentURI,  // full URL
112            'virtualPageTitle' : title,
113            'virtualPreviousPage': prevPage, // previous page, from which user come to current page
114            'login_status': loginStatus
115        };
116    },
117
118    /** PRÜFEN OB ES DIESES EVENT ÜBERHAUPT GIBT */
119    getViewOfProduct: function (product) {
120        return {
121            'event': 'view_item',
122            'ecommerce': {
123                'items': [{
124                    'item_id': product.sku,
125                    'item_name': product.name,
126                    'currency': "EUR",
127                    'item_brand': product.pva,
128                    'item_category': product.kind_of_product,
129                    'item_category2': product.praemie,     //Prämie, falls vorhanden
130                    'price': Vrm.Tracking.Functions.roundPrice(product.price),
131                    'quantity': product.quantity
132                }]
133            }
134        }
135    },
136
137    roundPrice: function (num) {
138        if (num === 'Ohne Laufzeit') {
139            return num;
140        }
141        return (Math.round(num * 100) / 100).toFixed(2);
142    },
143
144    getSuccessOrderData: function (data) {
145        let paymentMethod = Vrm.Tracking.Functions.mapPaymentMethod(data.paymentMethod);
146
147        let resultNew = {
148            'transaction_id': data.transactionId,
149            'email': data.email,
150            'affiliation': data.werbeaktionscodierung,
151            'value': Vrm.Tracking.Functions.roundPrice(data.transactionTotal),
152            'total_value': Vrm.Tracking.Functions.roundPrice(data.gesamtumsatz),
153            'tax': data.transactionTax,
154            'user_type': data.user_type,
155            'payment_frequent': data.paymentFrequent,
156            'payment_method': paymentMethod,
157            'currency': 'EUR',
158            'items': [
159                {
160                    'item_id': data.transactionProducts[0].sku,
161                    'item_id2': data.transactionProducts[0].campaignSku,
162                    'item_name': data.transactionProducts[0].name,
163                    'affiliation': data.werbeaktionscodierung,
164                    'currency': 'EUR',
165                    'item_brand': data.transactionProducts[0].pva,
166                    'item_category': data.transactionProducts[0].kind_of_product,
167                    'item_catgory2': data.transactionProducts[0].praemie,
168                    'price': Vrm.Tracking.Functions.roundPrice(data.transactionProducts[0].price),
169                    'quantity': data.transactionProducts[0].quantity,
170                }
171            ]
172        }
173
174        if (data.transactionProducts[1] !== undefined) {
175            let tablet = {
176                'item_id': data.transactionProducts[1].sku,
177                'item_name': data.transactionProducts[1].fullname, // Voller Name inkl. Varianten
178                'affiliation': data.werbeaktionscodierung,
179                'currency': 'EUR',
180                'item_brand': data.transactionProducts[1].name, // Modell
181                'item_category': 'Tablet', // Tablet
182                'item_variant': data.transactionProducts[1].variant, // Varianten
183                'price': Vrm.Tracking.Functions.roundPrice(data.transactionProducts[1].price),
184                'quantity': data.transactionProducts[1].quantity,
185            }
186            resultNew.items.push(tablet);
187        }
188
189        if (data.hostname_herkunft) {
190            resultNew['hostname_herkunft'] = data.hostname_herkunft;
191        }
192        if (data.articleOrigin) {
193            resultNew['articleOrigin'] = data.articleOrigin;
194        }
195
196        return {
197            'event': 'purchase',
198            'ecommerce': resultNew,
199        };
200    },
201
202    mapPaymentMethod: function (paymentMethod) {
203        switch(paymentMethod) {
204            case 'checkmo':
205                return 'Rechnung';
206            case 'creditcard':
207                return 'Kreditkarte';
208            case 'debitpayment':
209                return 'Lastschrift';
210            case 'paypal':
211                return 'Paypal';
212            case 'google_pay':
213                return 'GooglePay';
214            case 'apple_pay':
215                return 'ApplePay';
216            case 'free':
217                return 'Kostenlos';
218            default:
219                return '';
220        }
221    },
222
223    getCheckoutSteps: function(step,product) {
224        return {
225            'event': 'checkout',
226            'ecommerce': {
227                'checkout': {
228                    'actionField': {
229                        'step': step
230                    },
231                    'products': [{
232                        'name': product.name,
233                        'id': product.id,
234                        'price': Vrm.Tracking.Functions.roundPrice(product.price),
235                        'category': product.category,
236                        'quantity': 1
237                    }]
238                }
239            }
240        }
241    },
242
243    getPlzForPva: function () {
244        let element = document.getElementById('plz');
245        if (element) {
246            return {
247                'event':'sucheAusgabe',
248                'plz': element.value
249            };
250        }
251        return false;
252    },
253
254    login: function (sso_id) {
255        return {
256            'event': 'Login',
257            'userId': sso_id,
258        }
259    },
260
261    removeFromCart: function (data,product) {
262        if (product !== undefined) {
263            return {
264                'event': 'removeFromCart',
265                'ecommerce': {
266                    'items': [{ //  removing a product to a shopping cart.
267                        'item_id': data.sku,
268                        'item_name': data.fullname, // Voller Name inkl. Varianten
269                        'affiliation': product.werbeaktionscodierung,
270                        'currency': 'EUR',
271                        'item_brand': data.name, // Modell
272                        'item_category': 'Tablet', // Tablet
273                        'item_variant': data.variant, // Varianten
274                        'price': Vrm.Tracking.Functions.roundPrice(data.priceBol),
275                        'quantity': 1,
276                    }]
277                }
278            };
279        }
280    },
281
282    getProductImpressions: function (data,siteType) {
283        let items = [];
284        data.forEach(fillImpression);
285
286        function fillImpression(productObj) {
287            let item = {
288                'item_id': productObj.sku, // Name or ID is required.
289                'item_name': productObj.name,
290                'currency': 'EUR',
291                'index': productObj.pos,
292                'item_brand': productObj.pva,
293                'item_category': productObj.kind_of_product,
294                'item_category2': productObj.praemie,
295                'item_list_name': siteType,
296                'price': Vrm.Tracking.Functions.roundPrice(productObj.price),
297                'quantity': productObj.quantity
298            }
299            items.push(item);
300        }
301
302        return {
303            'event': 'view_item_list',
304            'ecommerce': {
305                'items': items
306            }
307        }
308    },
309
310    beginCheckout: function(product) {
311        let result = {
312            'event': 'begin_checkout',
313            'ecommerce': {
314                'items': [
315                    {
316                        'item_id': product.sku,
317                        'item_name': product.name,
318                        'affiliation': product.affiliation, // Werbeaktionscodierung
319                        'currency': "EUR",
320                        'item_brand': product.pva,
321                        'item_category': product.kind_of_product,
322                        'item_category2': product.praemie, //Prämie, falls vorhanden
323                        'price': Vrm.Tracking.Functions.roundPrice(product.price),
324                        'quantity': product.quantity
325                    }]
326            }
327        }
328
329        if (product.reason !== undefined) {
330            result.ecommerce.items[0].reason = product.reason;
331        }
332
333        return result;
334    },
335
336    /** VRMONLKUEN-45 - Auswahl des Kündigungsgrunds */
337    selectReason: function(reason) {
338        return {
339            'event': 'selectReason',
340            'reason': reason,
341        }
342    },
343
344    getProductClick: function(productObj,selPva = '') {
345        let pva = productObj.pva;
346        if (selPva !== '') {
347            pva = selPva;
348        }
349
350        return {
351            'event': 'select_item',
352            'ecommerce': {
353                'items': [{
354                    'item_id': productObj.sku, // Name or ID is required.
355                    'item_name': productObj.name,
356                    'currency': 'EUR',
357                    'index': productObj.pos,
358                    'item_brand': pva,
359                    'item_category': productObj.kind_of_product,
360                    'item_category2': productObj.praemie,
361                    'price': Vrm.Tracking.Functions.roundPrice(productObj.price),
362                    'quantity': productObj.quantity
363                }]
364            },
365        };
366    },
367
368    paymentFrequent: function(val) {
369        return {
370            'event':'choosePaymentFrequent',
371            'ecommerce': {
372                'paymentFrequent': val,
373            }
374        }
375    },
376
377    getNavigationClick: function(click) {
378        return {
379            'event': 'Navigation',
380            'eventAction': 'Klick auf Navigation',
381            'eventLabel': click,
382        };
383    },
384
385    getButtonClick: function(click) {
386        return {
387            'event': 'Buttons',
388            'eventAction': 'Klick auf Buttons',
389            'eventLabel': click,
390        };
391    },
392
393    shareInteraction: function (text,link) {
394        return {
395            'ShareButton': text,
396            'socialAction':'Teilen',
397            'event':'shareInteraction',
398            'socialTarget': link
399        };
400    },
401
402    getFooterClick: function (text) {
403        return {
404            'event':'footer_click',
405            'footer_link': text,
406        };
407    },
408
409    tradeTracker: function(data) {
410        if (Vrm.tt !== undefined && Vrm.tt.cid !== undefined && Vrm.tt.pid !== undefined) {
411            ttConversionOptions.push({
412                type: 'sales',
413                campaignID: Vrm.tt.cid,
414                productID: Vrm.tt.pid,
415                transactionID: data.transactionId,
416                transactionAmount: Vrm.Tracking.Functions.roundPrice(data.transactionTotal),
417                quantity: '1',
418                descrMerchant: '',
419                descrAffiliate: '',
420                vc: '',
421                currency: ''
422            });
423            (function (ttConversionOptions) {
424                let campaignID = 'campaignID' in ttConversionOptions ? ttConversionOptions.campaignID :
425                    ('length' in ttConversionOptions && ttConversionOptions.length ? ttConversionOptions[0].campaignID : null)
426
427                let tt = document.createElement('script');
428                tt.type = 'text/javascript';
429                tt.async = true;
430                tt.src = '//tm.tradetracker.net/conversion?s=' + encodeURIComponent(campaignID) + '&t=m';
431                let s = document.getElementsByTagName('script');
432                s = s[s.length - 1];
433                s.parentNode.insertBefore(tt, s);
434            })(ttConversionOptions);
435        }
436    },
437};
438Vrm.Tracking.Variables = Vrm.Tracking.Variables || {};
439
440Vc.Externallib = {
441
442    addToCart: function (data) {
443        return {
444            'event': 'addToCart',
445            'ecommerce': {
446                'currencyCode': 'EUR',
447                'add': {                                // 'add' actionFieldObject measures.
448                    'products': [{                        //  adding a product to a shopping cart.
449                        'name': data.name,
450                        'id': data.id,
451                        'price': data.price,
452                        'category': data.category,
453                        'quantity': 1
454                    }]
455                }
456            }
457        };
458    },
459
460    closeElement: function (box, isCategory = false) {
461        const textBox = box.querySelector(isCategory ? '.faqCatTextBox' : '.faqTextBox');
462        const buttonId = box.getAttribute('data-id');
463        const button = box.querySelector('button[data-id="' + buttonId + '"]');
464
465        button.setAttribute('aria-expanded', 'false');
466
467        // Falls noch ein alter Handler "in der Luft" hängt, sauber entfernen
468        if (textBox._onMaxHeightEnd) {
469            textBox.removeEventListener('transitionend', textBox._onMaxHeightEnd);
470            textBox._onMaxHeightEnd = null;
471        }
472
473        // Handler, der genau einmal nach Ende der max-height Transition feuert
474        textBox._onMaxHeightEnd = function (e) {
475            if (e.propertyName !== 'max-height') return;
476            textBox.style.display = 'none';
477
478            textBox.removeEventListener('transitionend', textBox._onMaxHeightEnd);
479            textBox._onMaxHeightEnd = null;
480        };
481
482        textBox.addEventListener('transitionend', textBox._onMaxHeightEnd);
483
484        // Transition starten
485        textBox.style.maxHeight = '0';
486
487        box.classList.remove('active');
488    },
489
490    openElement: function(box, isCategory = false) {
491        const textBox = box.querySelector(isCategory ? '.faqCatTextBox' : '.faqTextBox');
492        const buttonId = box.getAttribute('data-id');
493        const button = box.querySelector('button[data-id="' + buttonId + '"]');
494        button.setAttribute('aria-expanded', 'true');
495        textBox.style.removeProperty('display');
496        setTimeout(() => {
497            textBox.style.maxHeight = '100vh';
498        }, 0);
499        box.classList.add('active');
500        // if (isCategory) {
501        //     box.setAttribute('tabindex', '0');
502        // }
503    },
504
505    closeOtherElements: function(currentId, selector) {
506        document.querySelectorAll(selector + '.active').forEach(activeBox => {
507            if (activeBox.getAttribute('data-id') !== currentId) {
508                this.closeElement(activeBox, selector === '.faqCatBox');
509            }
510        });
511    },
512
513    triggerFaqCat: function(element) {
514        const faqId = element.getAttribute('data-id');
515        this.closeOtherElements(faqId, '.faqCatBox');
516
517        const box = document.querySelector('.faqCatBox[data-id="' + faqId + '"]');
518        if (box.classList.contains('active')) {
519            this.closeElement(box, true);
520        } else {
521            this.openElement(box, true);
522        }
523    },
524
525    triggerFaq: function(element) {
526        const faqId = element.getAttribute('data-id');
527        this.closeOtherElements(faqId, '.faqBox');
528
529        const box = document.querySelector('.faqBox[data-id="' + faqId + '"]');
530        if (box.classList.contains('active')) {
531            this.closeElement(box);
532        } else {
533            this.openElement(box);
534        }
535    }
536};
537
538document.addEventListener('readystatechange', function (){
539    if (document.readyState === 'complete') {
540        let pathname = window.location.pathname.split('/');
541        if (pathname[1] !== undefined && pathname[1] === 'abschluss') {
542            return false;
543        } else if(pathname[2] !== undefined && pathname[2] === 'abschluss') {
544            return false;
545        }
546        let data = Vrm.Tracking.Functions.getVirtualPageData();
547        Vrm.Tracking.Functions.pageViewPush(data);
548
549        /** VRMBFSG-8 - AUDIT-36 - Fokus bei Cookie-Banner muss direkt in das Modal springen */
550
551        let cmpID = 'cmpbox';
552
553        let cmpElement = document.getElementById(cmpID);
554
555        if (cmpElement) {
556            if (cmpElement.classList.contains('cmpboxclosed') === false) {
557                // Sucht nach dem ersten Link (mit href) oder Button innerhalb des Elements
558                let firstInteractiveElement = cmpElement.querySelector('a[href], button');
559
560                // Wenn ein Element gefunden wurde, Fokus setzen
561                if (firstInteractiveElement) {
562                    firstInteractiveElement.focus();
563                }
564            }
565        }
566    }
567});

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.