Сейчас узнаем, какой подарок выпадет именно Вам
Крутите колесо
Как сделать показ суммы при изменении количества товара Tilda

Как сделать показ суммы при изменении количества товара Tilda

1
Создали блок ST305N для работы с каталогом товаров
2
Добавили кнопку в корзину и кнопки количества товара
3
Добавили код в блок Т123
В основной и продуктовый footer
Mo-ti Level Up
Видео инструкции по добавлению кода и работе с Zero Block.
Как сделать показ суммы при изменении количества товара Tilda
Фрагмент видео
Библиотека для примера
<script>
(function() {
    'use strict';

    const qs = (sel, ctx = document) => ctx.querySelector(sel);
    const qa = (sel, ctx = document) => Array.from(ctx.querySelectorAll(sel));
    
    const formatPrice = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
    const parsePrice = txt => {
        if (!txt) return 0;
        let c = txt.trim().replace(/[₽€£¥\s]/g, '');
        if (c.includes(',') && c.includes('.')) c = c.replace(/,/g, '');
        else if (c.includes(',')) c = c.replace(',', '.');
        const n = parseFloat(c.replace(/[^\d.]/g, ''));
        return isNaN(n) ? 0 : n;
    };

    const TEMPLATE = `<div class="common-price-wrapper" style="display:none;opacity:0;transition:opacity .3s">
                            <div class="common-price-title t-descr t-descr_xxs"></div>
                            <div class="common-price-num t-name t-name_md">
                               <span class="col-summ"></span>
                            </div>
                        </div>`;


    function processCard(card, context = 'unknown') {
        if (card.dataset.priceProcessed) return;
        const pw = qs('.t-catalog__card__price-wrapper, .t-store__card__price-wrapper', card);
        if (!pw) return;

        pw.insertAdjacentHTML('afterend', TEMPLATE);
        const priceEl = qs('.js-product-price', card);
        const summEl = qs('.col-summ', card);
        if (priceEl && summEl) {
            summEl.textContent = priceEl.textContent.trim();
        }
        card.dataset.priceProcessed = 'true';
    }

    function processGrid(container) {
        if (!container) return;
        const cards = qa('.t-catalog__card, .t-store__card, .js-product-relevant', container);
        cards.forEach(card => processCard(card, 'GRID'));
    }

    function processPopup() {
        const popup = qs('.t-popup.t-popup_show');
        if (!popup || popup.dataset.popupProcessed) return;
        if (!qs('.js-product-price', popup)) return;

        const pw = qs('.t-catalog__prod-popup__price-wrapper, .t-store__prod-popup__price-wrapper', popup);
        if (pw) pw.insertAdjacentHTML('afterend', TEMPLATE);

        const priceEl = qs('.js-product-price', popup);
        const summEl = qs('.col-summ', popup);
        if (priceEl && summEl) summEl.textContent = priceEl.textContent.trim();
        popup.dataset.popupProcessed = 'true';
    }

    function processPopupRelevants() {
        const popup = qs('.t-popup.t-popup_show');
        if (!popup) return false;

        const containers = popup.querySelectorAll(
            '.t-store__relevants-grid-cont, .js-store-relevants-grid-cont, .t-catalog__relevants-grid-cont, .js-catalog-relevants-grid-cont'
        );

        if (containers.length === 0) return false; 

        let processedCount = 0;

        containers.forEach(container => {
            const cards = qa('.t-store__card, .t-catalog__card, .js-product-relevant', container);
            cards.forEach(card => {
                processCard(card, 'POPUP RELEVANTS');
                if (!card.dataset.priceProcessed) processedCount++; 
            });
        });

        return true; 
    }

    function waitForPopupRelevants() {
        let attempts = 0;
        const maxAttempts = 15;
        const interval = 200;

        const check = () => {
            attempts++;
            if (processPopupRelevants()) return; 

            if (attempts < maxAttempts) {
                setTimeout(check, interval);
            } else {
                console.warn('Relevants Timeout');
            }
        };
        setTimeout(check, interval);
    }

    function handleQty(e) {
        const target = e.target.closest('.t-catalog__prod__quantity-input, .t-store__prod__quantity-input, .t-catalog__prod__quantity__minus-wrapper, .t-catalog__prod__quantity__plus-wrapper, .t-store__prod__quantity__minus-wrapper, .t-store__prod__quantity__plus-wrapper, .js-product-controls-wrapper');
        if (!target) return;
        const block = target.closest('.js-product');
        if (!block) return;

        setTimeout(() => {
            const input = qs('.t-catalog__prod__quantity-input, .t-store__prod__quantity-input', block);
            const num = input ? (parseInt(input.value, 10) || 1) : 1;
            const priceEl = qs('.js-product-price', block);
            const currEl = qs('[class*="price-currency"]', block);
            const summEl = qs('.col-summ', block);
            const wrap = block.querySelector('.common-price-wrapper');
            if (!priceEl || !summEl) return;

            const val = parsePrice(priceEl.textContent);
            const curr = currEl?.textContent.trim() || '₽';
            const total = val * num;

            // Убрали Math.round. toFixed(2) защищает от артефактов JS (напр. 2800.6600000000003),
            // а parseFloat возвращает "естественный" вид (1400.33, 456.3, 456)
            const valF = parseFloat(val.toFixed(2));
            const totalF = parseFloat(total.toFixed(2));

            if (num > 1) {
                summEl.textContent = `${formatPrice(valF)} ${curr} × ${num} = ${formatPrice(totalF)} ${curr}`;
                if (wrap) { wrap.style.display = 'block'; requestAnimationFrame(() => wrap.style.opacity = '1'); }
            } else {
                summEl.textContent = `${formatPrice(valF)} ${curr}`;
                if (wrap) { wrap.style.opacity = '0'; setTimeout(() => wrap.style.display = 'none', 300); }
            }
        }, 150);
    }

    document.addEventListener('DOMContentLoaded', () => {
        qa('.js-catalog-grid-cont, .js-store-grid-cont').forEach(grid => {
            grid.addEventListener('tStoreRendered', () => processGrid(grid));
        });

        qa('.t-catalog__relevants-grid-cont, .js-catalog-relevants-grid-cont, .t-store__relevants-grid-cont, .js-store-relevants-grid-cont').forEach(grid => {
            grid.addEventListener('tStoreRendered', () => processGrid(grid));
        });

        setTimeout(() => qa('.t-catalog__relevants-grid-cont, .js-catalog-relevants-grid-cont, .t-store__relevants-grid-cont, .js-store-relevants-grid-cont').forEach(processGrid), 1500);
        setTimeout(() => qa('.js-catalog-grid-cont, .js-store-grid-cont, .t-catalog__relevants-grid-cont, .js-catalog-relevants-grid-cont, .t-store__relevants-grid-cont, .js-store-relevants-grid-cont').forEach(processGrid), 500);

        let popupReady = false;
        setInterval(() => {
            const popup = qs('.t-popup.t-popup_show');
            if (popup && !popupReady) {
                if (qs('.js-product-price', popup)) {
                    processPopup();
                    popupReady = true;
                }
            } else if (!popup) {
                popupReady = false;
            }
        }, 250);

        document.addEventListener('click', (e) => {
            if (e.target.closest('a[href*="/tproduct/"]')) {
                setTimeout(() => {
                    processPopup();          
                    waitForPopupRelevants();
                }, 300);
            }
        });

        document.addEventListener('click', handleQty, true);
        document.addEventListener('input', handleQty, true);
        document.addEventListener('change', handleQty, true);

        if (qs('.t-store__prod-snippet__container')) {
            setTimeout(() => {
                document.querySelectorAll('.common-price-wrapper').forEach(el => el.remove());
                const pw = qs('.t-catalog__prod-popup__price-wrapper, .t-store__prod-popup__price-wrapper, .t-catalog__card__price-wrapper, .t-store__card__price-wrapper');
                if (pw) pw.insertAdjacentHTML('afterend', TEMPLATE);
                const priceEl = qs('.js-product-price');
                const summEl = qs('.col-summ');
                if (priceEl && summEl) summEl.textContent = priceEl.textContent.trim();
            }, 300);
        }
    });
})();
</script>


<style>
.common-price-num {
    font-size: 14px;
    margin-top: 5px;
    font-weight: 400;
    margin-bottom: 5px;
}

.js-catalog-prod-price.t-catalog__prod-popup__price {
    font-size: 26px;
}
</style>
Made on
Tilda