Tilda · 6 мин чтения

Калькулятор стоимости на Тильду: как реализовать логику расчёта

Калькулятор стоимости на Тильду я собираю не из готового виджета, а из связки Zero Block, скрытого поля формы и небольшого JS-скрипта - так расчёт получается гибким, а итоговая цифра сразу улетает в заявку вместе с контактами. За последние пару лет сделал таких калькуляторов около двадцати: для строительной бригады, студии интерьера, доставки готовой еды, мастеров по ремонту техники. Логика везде разная, но каркас один и тот же. Ниже разберу его по шагам, покажу рабочий код и места, где расчёт обычно ломается.

Какие способы посчитать цену на Tilda есть и что я беру на практике

У Тильды нет полноценного конструктора калькуляторов из коробки. Есть пошаговая форма (блок с шагами), есть сторонние виджеты вроде uCalc, которые вставляются через embed, и есть путь через собственный JS в HTML-блоке T123. Я перепробовал все три и для большинства проектов остановился на последнем.

Вот как я сравниваю варианты, когда выбираю подход под конкретную задачу:

Способ Гибкость формул Внешний вид Когда беру
Пошаговая форма Tilda Низкая: только сумма чекбоксов Ограничен настройками блока Простой прайс без множителей
Сторонний виджет (uCalc) Средняя Свой, но чужеродный дизайну Нужно быстро и без кода
Свой JS в Zero Block + T123 Высокая: любые формулы и API Полностью под макет сайта Множители, скидки, оплата, доставка

Пошаговая форма умеет складывать цены выбранных опций и на этом её математика заканчивается. Как только заказчик говорит «а если больше 100 квадратов - коэффициент 0,9» или «доставка считается по километрам от МКАД», встроенного функционала уже не хватает. Поэтому дальше я разбираю именно самописный вариант - он закрывает и простые случаи, и сложные.

Логика расчёта: где держать цены и формулы

Главная ошибка новичков - зашивать цены прямо в JavaScript. Через месяц заказчик просит поднять тариф на 5000 ₽, лезет в код, ставит запятую не там, и весь онлайн-калькулятор перестаёт считать. Я держу цены в HTML-разметке через атрибуты data-price, а скрипт их только читает. Тогда правки вносятся в привычном визуальном редакторе Zero Block, а логику трогать не нужно.

Саму цену я раскладываю на три слагаемых:

  • Базовый тариф - то, что выбирают радиокнопкой: лендинг, многостраничник, интернет-магазин.
  • Опции - чекбоксы с фиксированной надбавкой: интеграция с CRM, копирайтинг, мультиязычность.
  • Количественные поля - число страниц, квадратных метров, километров, умноженное на цену за единицу.

Сверху накидываю коэффициенты. Срочный заказ - умножение итога на 1,3. Оптовый объём - на 0,9. Коэффициенты тоже удобнее хранить в data-атрибутах, а не в теле функции. На проекте для доставки еды я так вынес в разметку даже стоимость каждого соуса - заказчик сам правил её перед праздниками, ко мне не обращаясь.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Скрипт расчёта в HTML-блоке T123

Сначала размечаю поля. В Zero Block удобно нарисовать интерфейс блоками, но сам расчётный контейнер я держу в блоке T123 (HTML-код), чтобы контролировать идентификаторы и атрибуты. Минимальная разметка выглядит так:

<div id="calc">
  <label><input type="radio" name="tariff" data-price="30000" checked> Лендинг</label>
  <label><input type="radio" name="tariff" data-price="60000"> Многостраничник</label>
  <label><input type="checkbox" class="option" data-price="8000"> Интеграция с CRM</label>
  Страниц: <input type="number" id="pages" value="1" min="1">
  <div id="calc-total">30 000 ₽</div>
</div>

Дальше - скрипт. Он вешает пересчёт на любое изменение внутри контейнера и обновляет и видимую сумму, и скрытое поле формы:

document.addEventListener('DOMContentLoaded', function () {
  var calc = document.querySelector('#calc');
  var out = document.querySelector('#calc-total');

  function recalc() {
    var total = 0;
    var tariff = calc.querySelector('input[name="tariff"]:checked');
    if (tariff) total += parseInt(tariff.dataset.price, 10);

    calc.querySelectorAll('.option:checked').forEach(function (opt) {
      total += parseInt(opt.dataset.price, 10);
    });

    var pages = parseInt(document.querySelector('#pages').value, 10) || 0;
    total += pages * 1500;

    out.textContent = total.toLocaleString('ru-RU') + ' ₽';

    var hidden = document.querySelector('input[name="Стоимость"]');
    if (hidden) hidden.value = total;
  }

  calc.addEventListener('change', recalc);
  calc.addEventListener('input', recalc);
  recalc();
});


Обратите внимание на две вещи. Первое - || 0 после parseInt: если пользователь очистит поле, вернётся NaN, и без этой подстраховки вся сумма превратится в «NaN ₽». Второе - toLocaleString('ru-RU') ставит красивые пробелы между разрядами, чтобы 45000 читалось как 45 000. Мелочь, но без неё цифры выглядят дёшево.

Чтобы не собирать такой каркас каждый раз с нуля, часть заготовок под расчёт и передачу данных я держу в открытом виде - готовые скрипты для Тильды можно взять за основу и допилить под свой прайс.

Связываю онлайн-калькулятор с формой, оплатой и доставкой

Считать сумму на экране мало - её нужно довести до заявки и до денег. Здесь начинается самое интересное.

Передача суммы в форму заявки

В форме Tilda я добавляю скрытое поле с именем, например, Стоимость. Скрипт из примера выше кладёт туда итог при каждом пересчёте. Когда человек жмёт «Отправить», рассчитанная цифра уходит в письмо, в CRM и в подключённые интеграции ровно так же, как имя и телефон. На проекте с amoCRM это избавило менеджеров от ручного пересчёта - заявка сразу приходила с суммой и составом заказа.

Оплата и доставка

Если к форме подключён приём платежей через T‑Bank (бывший Тинькофф) или ЮKassa, итоговая сумма из скрытого поля уходит в платёжку как сумма к оплате. Для интернет-магазина на WooCommerce, когда Тильда работает витриной, я отдаю расчёт через вебхук в n8n, а тот уже создаёт заказ на нужную цену. Стоимость доставки СДЭК подтягиваю тем же способом: скрипт отправляет город и вес в вебхук, n8n дёргает API СДЭК и возвращает цену, которую калькулятор прибавляет к итогу. Дополнительно вешаю уведомление в Telegram через aiogram-бота - новая заявка с суммой падает в рабочий чат за секунду, менеджер видит её раньше, чем письмо на почте.

Ошибки, из-за которых калькулятор считает неверно

Собрать логику - половина дела. Вторая половина - чтобы она не сломалась на живых пользователях. Вот что ловлю чаще всего:

  1. Скрипт запускается раньше вёрстки. Zero Block грузится асинхронно, и если не обернуть код в DOMContentLoaded, querySelector вернёт null. Обязательно дожидаюсь загрузки DOM.
  2. Забытый parseInt. Значения из data-price и полей приходят строками. Без приведения к числу вместо сложения получится склейка: «30000» + «8000» = «300008000».
  3. Точка вместо запятой в коэффициентах. В JS десятичный разделитель - точка. Коэффициент 0,9, записанный как 0,9, вызовет синтаксическую ошибку.
  4. Не тот тип события. Для чекбоксов и радиокнопок работает change, а для полей ввода числа лучше input, чтобы сумма менялась по мере набора. Я вешаю оба.
  5. Мобильная вёрстка. На телефоне Zero Block часто дублирует блоки под отдельный брейкпоинт. Если идентификатор #calc встречается дважды, скрипт цепляется к первому и на мобильном ничего не считает. Держу расчётный контейнер в одном экземпляре.

Отдельно проверяю поведение при нуле и пустых полях. Пользователь стирает количество страниц - сумма не должна улетать в минус или в NaN. Пара строк с Math.max(0, value) закрывает почти все крайние случаи.

Когда стандартных блоков не хватает

Кастомный скрипт

от 3 000 ₽

Подробнее →

Частые вопросы

Можно ли сделать калькулятор на Тильде без кода?

Да, через пошаговую форму или сторонний виджет вроде uCalc. Это годится, когда цена - простая сумма выбранных опций. Как только появляются коэффициенты, расчёт доставки или передача итога в оплату, без JS в блоке T123 уже не обойтись.

Как передать итоговую сумму в форму заявки?

В форму добавляется скрытое поле с понятным именем, например «Стоимость», а скрипт при каждом пересчёте записывает туда значение. Дальше сумма уходит в письмо, CRM и платёжную систему вместе с контактами клиента.

Правильно ли калькулятор считает на мобильных?

Считает, если следить за идентификаторами. Zero Block на мобильном брейкпоинте иногда дублирует блоки, и тогда скрипт цепляется не к тому контейнеру. Держу расчётный блок в единственном экземпляре и тестирую на реальном телефоне, а не только в превью.

Сколько времени занимает разработка такого калькулятора?

Простой калькулятор из тарифа и трёх опций я собираю за 3-4 часа вместе с вёрсткой и тестами. Вариант с коэффициентами, расчётом доставки СДЭК через API и уведомлением в Telegram занимает 1-2 дня - основное время уходит на согласование формул и проверку крайних случаев, а не на сам код.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно