Калькулятор стоимости междугороднего такси на Тильде
Актуально на декабрь 2025 годаЭта страница — пошаговая инструкция для тех, кто делает сайт на Tilda и хочет добавить на него калькулятор предварительной стоимости поездки между городами. Мы будем считать стоимость по реальному расстоянию по дорогам, используя API сервиса Avtodispetcher.
Мануал подойдёт:
- владельцам и разработчикам сайтов служб такси и трансферов;
- дизайнерам и интеграторам на Тильде;
- любому, кто хочет быстро собрать работающий калькулятор расстояний без бэкенда.
Предполагается, что вы уже знакомы с базовой работой в Tilda (создание страницы, блоки, формы), но подробно в JavaScript разбираться не обязательно — готовый код можно просто вставить и слегка адаптировать под свой проект.
Как это работает в общих чертах
Схема работы калькулятора выглядит так:
- На странице Тильды есть обычная форма с полями "Откуда" и "Куда".
- При вводе названий городов срабатывают подсказки — мы берём их из API Avtodispetcher.
- Когда оба поля заполнены, наш JavaScript в фоне вызывает API построения маршрута.
- API возвращает расстояние по дорогам (в километрах), а не "по прямой".
- JavaScript записывает это расстояние в поле формы "Расстояние".
- Встроенный тильдовский блок "Калькулятор" подставляет расстояние из поля в формулу тарифа и считает цену.
- Пользователь видит предварительную стоимость поездки, а при отправке формы все данные (города, расстояние, цена) уходят в почту и/или CRM в соответствии с настройками формы Тильды.
Как выглядит результат на Тильде
Важный акцент: вся визуальная часть и итоговая формула тарифа находятся на стороне Тильды, а API Avtodispetcher отвечает только за одно — точно посчитать расстояние между указанными городами.
Что понадобится перед началом
1. Тариф Тильды с поддержкой HTML-блоков
Для вставки собственного JavaScript понадобится тариф Tilda, в котором доступен блок "Т123. HTML" или возможность вставить код в настройках страницы (HTML-код для вставки внутрь head). На бесплатном тарифе этого нет, поэтому по состоянию на момент написания статьи описанная ниже схема там не заработает. Проверьте тарифы и возможности Тильды здесь.
2. API-ключ для Avtodispetcher
Калькулятор использует два метода API:
- подсказки городов (autocomplete),
- построение маршрута и получение расстояния.
Если API-ключа ещё нет, получить его можно здесь. Без ключа калькулятор работать не будет — запросы к API будут возвращать ошибки авторизации.
Понадобится настроенный CORS для вашего домена — при получении API-ключа сообщите в поддержку домен сайта, чтобы мы добавили его в белый список.
3. Минимальные знания
- умение редактировать блок формы в Тильде;
- умение задать полю формы атрибут "name" (это важно для формулы калькулятора);
- умение вставить готовый JS-код в HTML-блок или в настройки страницы.
Весь JavaScript мы дадим в готовом виде, достаточно будет:
- подставить свой API-ключ,
- убедиться, что названия полей в форме совпадают с теми, что используются в коде.
Общий план интеграции
Чтобы не утонуть в деталях, сначала посмотрим на процесс целиком.
- Создаём на странице Тильды форму заказа поездки.
- Настраиваем в этой форме поля:
- "from_city" — откуда едем;
- "to_city" — куда едем;
- "distance" — расстояние в километрах (будет заполняться скриптом);
- калькулятор Тильды - настраиваем в нем формулу тарифа, например "500 + distance * 35"
- дополнительные поля: имя, телефон, комментарий и т.п.
- Вставляем на страницу JavaScript, который:
- подключает подсказки городов к полям "from_city" и "to_city";
- после выбора городов вызывает API маршрута;
- записывает полученное расстояние в поле "distance".
- Проверяем: вводим города, убеждаемся, что расстояние и цена считаются автоматически.
Дальше по шагам мы развернём каждый пункт, начнём с формы.
Подготовка формы на Тильде
1. Создаём форму заказа
Добавьте на страницу стандартный блок формы Тильды (любой, который вам нравится визуально):
- поле "Откуда" — текстовое поле,
- поле "Куда" — текстовое поле,
- поле "Расстояние в км" — текстовое поле,
- поле "Предварительная стоимость поездки" — с типом "Калькулятор",
- остальные поля (имя, телефон, комментарий) — по вашему усмотрению.
Далее нам нужно задать этим полям правильные имена переменных — именно по ним JavaScript и калькулятор будут находить значения.
2. Важные имена полей (html-атрибут name)
Последовательно открывайте настройки каждого поля формы и задавайте следующие имена переменных:
- поле "Откуда" - имя переменной "from_city"
- поле "Куда" - имя переменной "to_city"
- поле "Расстояние в км" - имя переменной "distance"
Текстовые подписи, placeholder'ы и внешний вид могут быть любыми — критично именно значение "имя переменной".
3. Почему поле distance должно быть видимым
Логично захотеть спрятать расстояние от пользователя и сделать поле "distance" скрытым: <input type="hidden">. К сожалению, на практике это не работает.
По состоянию на момент написания статьи компонент "Калькулятор" в Тильде не подставляет значения из скрытых полей в формулу. То есть JavaScript сможет записать расстояние в hidden-поле, но калькулятор это значение оттуда не подхватит.
Поэтому поле "distance" должно быть обычным текстовым полем. Чтобы пользователь не мог вручную изменить расстояние и занизить цену, JavaScript сделает поле доступным только для чтения: <input type="text" name="distance" readonly>
В результате:
- пользователь видит рассчитанное расстояние в километрах (что само по себе полезно);
- не может его изменить руками;
- калькулятор корректно использует "distance" в формуле тарифа.
Настройка формы на Тильде
На этом подготовка формы завершена. На следующем шаге мы добавим JavaScript-код, который подключит подсказки городов и автоматический расчёт расстояния через API Avtodispetcher.
Добавляем JavaScript-код на страницу
Теперь нам нужно подключить логику подсказок и расчёта расстояния. Для этого мы вставим на страницу небольшой JavaScript-фрагмент. Он:
- отслеживает ввод в полях "from_city" и "to_city";
- подгружает подсказки городов из API;
- после выбора городов запрашивает маршрут и расстояние по API;
- записывает расстояние в поле "distance" (в километрах).
В Тильде (на платном тарифе) есть два варианта, куда вставить код:
- в блок "Т123. HTML" прямо на нужной странице;
- в настройках страницы, в секции "дополнительно", пункт "HTML-код для вставки внутрь head".
Ниже — JavaScript код для вставки. Нужно подставить свой API-ключ вместо "YOUR_BASE64_KEY_HERE".
<script>
(function () {
'use strict';
// === НАСТРОЙКИ ===
const API_BASE = 'https://api.avtodispetcher.ru/v1';
const API_KEY = 'YOUR_BASE64_KEY_HERE'; // сюда подставьте свой ключ base64(login:password)
// Имена полей формы (атрибут name)
const FIELD_FROM_NAME = 'from_city';
const FIELD_TO_NAME = 'to_city';
const FIELD_DISTANCE_NAME = 'distance';
// ID контейнеров для подсказок
const SUGGESTIONS_FROM_ID = 'from-suggestions';
const SUGGESTIONS_TO_ID = 'to-suggestions';
// === ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ===
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// Получение расстояния между двумя городами
async function getDistance(from, to) {
const url = API_BASE + '/route?from=' +
encodeURIComponent(from) + '&to=' + encodeURIComponent(to);
const response = await fetch(url, {
headers: {
'accept': 'application/json',
'Authorization': 'Basic ' + API_KEY
}
});
const data = await response.json();
if (typeof data.kilometers === 'number') {
return data.kilometers;
}
throw new Error('Не удалось определить расстояние');
}
// === ОСНОВНАЯ ЛОГИКА ===
function initCalculator() {
const fromInput = document.querySelector('input[name="' + FIELD_FROM_NAME + '"]');
const toInput = document.querySelector('input[name="' + FIELD_TO_NAME + '"]');
const distanceField =
document.querySelector('input[name="' + FIELD_DISTANCE_NAME + '"]');
if (!fromInput || !toInput || !distanceField) {
console.warn(
'Не найдены поля формы: ' +
FIELD_FROM_NAME + ', ' + FIELD_TO_NAME + ', ' + FIELD_DISTANCE_NAME
);
return;
}
distanceField.readOnly = true;
let lastQueryId = 0;
async function recalcIfReady() {
const fromCity = fromInput.value.trim();
const toCity = toInput.value.trim();
if (!fromCity || !toCity) {
distanceField.value = '';
return;
}
const queryId = ++lastQueryId;
try {
const distance = await getDistance(fromCity, toCity);
if (queryId !== lastQueryId) return;
distanceField.value = distance.toFixed(0);
distanceField.dispatchEvent(new Event('input', { bubbles: true }));
distanceField.dispatchEvent(new Event('change', { bubbles: true }));
} catch (err) {
console.error(err);
}
}
const recalcIfReadyDebounced = debounce(recalcIfReady, 400);
attachCitySuggestions(fromInput, SUGGESTIONS_FROM_ID, recalcIfReadyDebounced);
attachCitySuggestions(toInput, SUGGESTIONS_TO_ID, recalcIfReadyDebounced);
}
// Подключаем подсказки
function attachCitySuggestions(inputEl, suggestionsId, onChangeCallback) {
let lastQueryId = 0;
let suppressNextSuggestions = false;
const wrapper = document.createElement('div');
wrapper.style.position = 'relative';
wrapper.style.display = 'block';
wrapper.style.width = '100%';
inputEl.parentNode.insertBefore(wrapper, inputEl);
wrapper.appendChild(inputEl);
const cs = window.getComputedStyle(inputEl);
const container = document.createElement('div');
container.id = suggestionsId;
container.style.position = 'absolute';
container.style.top = cs.height || '100%';
container.style.left = '0';
container.style.right = '0';
container.style.zIndex = '9999';
container.style.boxSizing = 'border-box';
container.style.maxHeight = '200px';
container.style.overflowY = 'auto';
container.style.display = 'none';
container.style.fontFamily = cs.fontFamily;
container.style.fontSize = cs.fontSize;
container.style.lineHeight = cs.lineHeight;
container.style.backgroundColor =
(cs.backgroundColor && cs.backgroundColor !== 'rgba(0, 0, 0, 0)')
? cs.backgroundColor
: '#ffffff';
container.style.borderStyle = cs.borderBottomStyle || 'solid';
container.style.borderWidth = cs.borderBottomWidth || '1px';
container.style.borderColor = cs.borderBottomColor || '#000';
wrapper.appendChild(container);
async function getCitySuggestionsForInput(query) {
if (!query || query.length < 2) {
container.style.display = 'none';
container.innerHTML = '';
return;
}
const currentId = ++lastQueryId;
const url = API_BASE +
'/cities?q=' + encodeURIComponent(query) +
'&limit=5&onlyCountries[]=RU';
try {
const response = await fetch(url, { headers: { 'accept': 'application/json' } });
const data = await response.json();
if (currentId !== lastQueryId) return;
showSuggestionsForInput(data, inputEl, container);
} catch (err) {
console.error('Ошибка при запросе городов:', err);
}
}
function showSuggestionsForInput(suggestions, inputEl, container) {
container.innerHTML = '';
if (!Array.isArray(suggestions) || suggestions.length === 0) {
container.style.display = 'none';
return;
}
suggestions.forEach(city => {
const item = document.createElement('div');
item.className = 't-descr t-suggestion-item';
item.style.padding = '10px 12px';
item.style.cursor = 'pointer';
item.textContent = city;
item.addEventListener('click', () => {
suppressNextSuggestions = true;
inputEl.value = city;
inputEl.dispatchEvent(new Event('input', { bubbles: true }));
container.style.display = 'none';
});
container.appendChild(item);
});
container.style.display = 'block';
}
const debouncedInputHandler = debounce((e) => {
const value = e.target.value;
if (suppressNextSuggestions) {
suppressNextSuggestions = false;
} else {
getCitySuggestionsForInput(value);
}
if (typeof onChangeCallback === 'function') {
onChangeCallback();
}
}, 300);
inputEl.addEventListener('input', debouncedInputHandler);
}
// Старт
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initCalculator);
} else {
initCalculator();
}
})();
</script>
Вставка JavaScript-кода в блок "Т123. HTML" в Тильде
Настройка калькулятора тарифа в Тильде
Ниже несколько вариантов простых формул тарифа, которые часто используются в практике:
-
Базовый междугородний тариф:
500 + distance * 35
где 500 ₽ — стоимость подачи, 35 ₽ — цена за 1 км. -
Только цена за километр:
distance * 25 -
Два класса авто (эконом / комфорт):
Если у вас есть поле с выпадающим списком классов авто, то в нем можно задать коэффициент (или цену за километр) для последующего использования в формуле. Подробнее об использовании выпадающего списка в калькуляторе описано в хелпе Тильды.
На следующем шаге имеет смысл пройтись по чек-листу и проверить, что всё работает: подсказки городов появляются, расстояние считается, цена обновляется, данные приходят в почту.
Чек-лист: проверяем, что всё работает
Прежде чем выкатывать калькулятор на боевой сайт, удобно пройтись по короткому чек-листу.
- На странице есть форма с полями "Откуда", "Куда", "Расстояние в км".
- Поле "distance" — видимое текстовое поле, а не hidden.
- JavaScript вставлен либо в HTML-блок, либо в настройки страницы.
- В JavaScript подставлен ваш реальный API-ключ
- После загрузки страницы в консоли браузера (F12 → вкладка Console) нет красных ошибок JavaScript.
- При наборе первых трех-четырех букв в поле "Откуда" появляется выпадающий список городов.
- Выбор города из списка подставляет название в поле и закрывает список.
- Аналогично работает поле "Куда".
- После заполнения обоих полей "Откуда" и "Куда" через секунду-другую в поле "Расстояние в км" появляется число.
- Число выглядит реалистично (например, "Самара → Воронеж" не равно 5 км).
- Под формой обновляется значение предварительной стоимости (калькулятор Тильды).
- При отправке формы заявка успешно уходит (нет красных сообщений об ошибке).
- В письме/CRM карточке заказа видно:
- значения полей "from_city" и "to_city";
- значение "distance" в километрах;
- итоговую сумму, рассчитанную калькулятором (если вы выводите её как отдельное поле).
Подводные камни Тильды и способы их обойти
Ниже — особенности, с которыми приходилось сталкиваться на реальных проектах. Зная о них заранее, вы сэкономите себе несколько часов экспериментов.
1. Скрытые поля не работают в калькуляторе
Уже упоминали, но повторим отдельно: на момент написания статьи блок "Калькулятор" в Тильде не использует значения полей типа "hidden" в формулах.
Решение — использовать обычное текстовое поле и пометить его как "readonly". Также можно сделать текстовое поле более "скромным" (меньший шрифт, меньший размер, подпись "для диспетчера", перенос вниз формы и т.п.).
На многих сайтах такси пользователю наоборот полезно видеть рассчитанное расстояние, это повышает доверие к цене.
2. Нельзя надёжно перехватить отправку формы
В Тильде свои внутренние обработчики события "submit" формы. В ряде шаблонов они срабатывают первыми, и отменить отправку формы через ваш JavaScript невозможно.
Поэтому мы сознательно не вмешиваемся в процесс отправки формы:
- весь расчёт происходит до отправки — на этапе ввода городов;
- мы просто записываем расстояние в поле "distance", а дальше Тильда делает своё дело.
Это делает интеграцию более устойчивой.
3. Несколько форм на странице
В базовом примере мы ориентируемся на первую форму с полями "from_city", "to_city" и "distance":
const FIELD_FROM_NAME = 'from_city';
const FIELD_TO_NAME = 'to_city';
const FIELD_DISTANCE_NAME = 'distance';
Если на странице несколько форм с похожими полями, имеет смысл:
- либо ограничиться одной "основной" формой под калькулятор,
- либо доработать JS так, чтобы каждый его экземпляр работал со "своими" полями.
4. Внешний вид подсказок
В разных шаблонах Тильды поля могут выглядеть по-разному: тёмная тема, большие поля, рамки только снизу и т.п. Чтобы подсказки визуально к ним подходили, скрипт использует getComputedStyle и подстраивает шрифт, фон и рамку под конкретный инпут.
Если в каком-то шаблоне подсказки выглядят "чужеродно", можно:
- добавить к элементам подсказок собственный CSS-класс и слегка подправить отступы/фон;
- либо, наоборот, убрать часть автоматических стилей и задать внешний вид вручную.
5. Превью-страницы Тильды могут не работать из-за CORS
Когда вы просматриваете страницу через стандартное превью Тильды (на служебных доменах вроде tilda.ws), браузер выполняет запросы к API с этого временного домена. Поскольку такой домен не добавлен в белый список CORS, запросы блокируются, и калькулятор кажется неработающим.
Это нормальное поведение: в целях безопасности API отвечает только на запросы с заранее разрешённых доменов.
Как решить:
- публикуйте страницу на вашем реальном домене (даже если это черновик);
- убедитесь, что ваш домен добавлен в CORS-список в поддержке Avtodispetcher;
- проверяйте работу калькулятора только на вашем домене, а не в превью Тильды.
После публикации на вашем домене и корректной настройки CORS всё будет работать штатно.
Что дальше
На этом всё необходимое для запуска калькулятора готово: форма на Тильде настроена, JavaScript подставляет расстояние, калькулятор считает цену, а заявка уходит в почту или CRM вместе с городами и километрами.
Дальше вы можете развивать эту схему под свои задачи:
- добавлять разные тарифы (эконом / комфорт / бизнес);
- применять надбавки за ночное время, большие группы, ожидание и другие условия;
- использовать дополнительные переменные и формулы калькулятора Тильды;
- расширить форму, чтобы она подходила под ваш реальный бизнес-процесс.
Нужна помощь с интеграцией?
Можно написать напрямую разработчику API - Илье Гуку.
Обсудим задачу, подскажу по запросам и подводным камням интеграции. Кратко опишите проект и где планируете использовать API. Обычно отвечаю в рабочие дни в течение дня.
Telegram: @ilyaguk Email: support@avtodispetcher.ru Форма обратной связи: здесь