PageSourceSearch

https://somnishop.co.uk/wp-content/themes/somnishop-amp-new/assets/js/snore-test-result-product.js?ver=7.1.2

js somnishop.co.uk collected 2026-10-10 00:06:34 UTC 4,815 bytes, 115 lines download raw bytes

1class SnoreTestResultProduct {
2    constructor() {
3        this.instances = [];
4        document.querySelectorAll('.product').forEach((productEl, index) => {
5            const instance = index + 1;
6            const variationsJson = document.querySelector(`#variationsData${index > 0 ? '-' + instance : ''}`)?.innerHTML;
7            if (variationsJson) {
8                this.instances.push({
9                    element: productEl,
10                    variations: JSON.parse(variationsJson),
11                    instance: instance
12                });
13            }
14        });
15        this.init();
16    }
17
18    init() {
19        document.querySelectorAll('.variation select').forEach(select => {
20            select.addEventListener('change', (e) => this.handleVariationChange(e));
21        });
22    }
23
24    handleVariationChange(event) {
25        const select = event.target;
26        const productEl = select.closest('.product');
27        const instanceObj = this.instances.find(inst => inst.element === productEl);
28        if (!instanceObj) return;
29
30        const variations = instanceObj.variations;
31        let variationSlug = '';
32
33        // Build slug from all selects in this product column
34        productEl.querySelectorAll('.variation select').forEach(sel => {
35            const selected = sel.options[sel.selectedIndex];
36            variationSlug += selected.value;
37        });
38
39        this.setVariation(variationSlug, instanceObj);
40    }
41
42    setVariation(variationSlug, instanceObj) {
43        const variation = instanceObj.variations[variationSlug];
44        const productEl = instanceObj.element;
45
46        if (!variation || !variation.attributes) {
47            // disable add to cart, hide qty
48            productEl.querySelector('.snore-test-result-add-to-cart')?.setAttribute('disabled', '');
49            productEl.querySelectorAll('.product-qty').forEach(qty => qty.classList.add('--hidden'));
50            return;
51        }
52
53        // Set hidden inputs (if any)
54        for (const [key, value] of Object.entries(variation.attributes)) {
55            productEl.querySelectorAll(`input[name="${key}"]`).forEach(input => input.value = value);
56        }
57
58        // Update add-to-cart link
59        const couponPart = productEl.querySelector('.snore-test-result-add-to-cart')?.getAttribute('href').split('&')[1] || '';
60        productEl.querySelector('.snore-test-result-add-to-cart')?.setAttribute(
61            'href',
62            `/?add-to-cart=${variation.variation_id}&${couponPart}`
63        );
64
65        // Update stock / qty label
66        productEl.querySelectorAll('.product-qty').forEach(qty => {
67            qty.classList.remove('--hidden', 'low-stock', 'no-stock', 'backorder');
68            if (variation.max_qty >= 20) {
69                qty.classList.add('visually-hidden');
70                qty.setAttribute('aria-hidden', 'true');
71            } else if (variation.is_on_backorder) {
72                qty.classList.remove('visually-hidden');
73                qty.classList.add('backorder');
74            } else if (variation.max_qty > 0 && variation.max_qty <= 19) {
75                qty.classList.remove('visually-hidden');
76                qty.classList.add('low-stock');
77            } else {
78                qty.classList.remove('visually-hidden');
79                qty.classList.add('no-stock');
80            }
81            qty.innerHTML = variation.quantity_label;
82            qty.removeAttribute('aria-hidden');
83        });
84
85        // Enable/disable add-to-cart
86        const btn = productEl.querySelector('.snore-test-result-add-to-cart');
87        if (variation.is_in_stock) {
88            btn?.removeAttribute('disabled');
89        } else {
90            btn?.setAttribute('disabled', '');
91        }
92
93        // Update price
94        const priceContainer = productEl.querySelector('.price.variation-price');
95        const percentage = parseFloat(priceContainer?.dataset.percentage_discount) || 0;
96        const cleanPrice = parseFloat(variation.price_formatted.replace(/[^\d.,]/g, '').replace(',', '.'));
97        let finalPrice = cleanPrice;
98        if (percentage > 0) {
99            finalPrice = cleanPrice - (cleanPrice * percentage / 100);
100        }
101
102        // Update original & discount price
103        productEl.querySelectorAll(".variation-price .product-price-original .woocommerce-Price-amount").forEach(el => {
104            el.innerHTML = variation.price_formatted;
105        });
106        productEl.querySelectorAll(".variation-price .discount-price .woocommerce-Price-amount").forEach(el => {
107            const symbol = variation.price_formatted.replace(/[0-9.,\s]/g, '');
108            el.innerText = finalPrice.toFixed(2).replace('.', ',') + ' ' + symbol;
109        });
110    }
111}
112
113document.addEventListener('DOMContentLoaded', () => {
114    window.snoreTestResultProduct = new SnoreTestResultProduct();
115});

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.