После успешной отправки формы: сообщение, переход или попап
«Форма отправилась — и исчезла», «нужен попап вместо зелёной плашки», «хочу обратиться по имени в ответе». Всё три вещи Тильда умеет сама, и умеет глубже, чем кажется: у неё есть родной блок сообщения, событие на форме, переменные из полей и номер заявки. Часть этого выключена в восьми типах блоков, включая Zero Block, — и это единственная причина, по которой одна и та же настройка у одного работает, а у другого нет.
Короткий ответ
Тильда это умеет сама. У формы есть блок .js-successbox: он заполняется текстом из
настроек, понимает {{form.Name}} и {{tilda.lead_id}} и показывается инлайновым
display: block. Форму она не прячет — очищает поля. Своему коду нужно событие
tildaform:aftersuccess на форме; оно приходит до того, как бокс показан.
Что происходит после успешного ответа сервера: по шагам
Порядок важен, потому что почти все поломки — это код, вставленный не в тот шаг.
Читается он прямо из tilda-forms-1.0.min.js:
- Отправляется событие статистики.
tildaform:aftersuccessна элементе формы. Всплывающее,cancelable: false— отменить его нельзя.- Вызывается колбэк из
data-formsended-callback, если он есть, черезeval. window.tildaForm.successEnd(): форме добавляется классjs-send-form-success.- Обновляются системные переменные (сюда попадает номер заявки).
- Заполняется
.js-successbox, в нём подставляются переменные, и он показывается:e.style.display = "block"— или, если у формыdata-success-popup="y", вместо этого открывается попап. - И только теперь —
t_forms__handleSuccess: либо ваш колбэк из настроек, либо переход на страницу успеха. - Очищаются значения полей и данные формы.
Отсюда два следствия, которых из интерфейса не видно. Первое: событие приходит раньше, чем показан бокс, — значит на нём можно бокс подменить, и человек увидит уже ваш вариант, без мигания. Второе: поля очищаются последними, поэтому прочитать введённое имя на событии ещё можно, а через секунду — уже нет.
Сценарий 1: сообщение на месте формы
Тильда показывает сообщение над полями, а не вместо них. Разметка из реальной страницы — блок стоит первым внутри формы:
<div class="js-successbox t-form__successbox t-text t-text_md"
aria-live="polite" style="display:none;"></div>
aria-live="polite" там уже есть — то есть посетитель со скринридером услышит
сообщение, когда оно появится, и это Тильда сделала за вас. Своя плашка вместо
этого блока такое свойство потеряет.
Текст задаётся в настройках формы, полем «Сообщение после отправки». Если хочется, чтобы поля при этом исчезли, — это одна строка CSS, потому что нужный класс Тильда уже поставила:
/* В блок T123 на странице или в настройках сайта → CSS.
Класс js-send-form-success появляется на форме после успеха. */
.js-send-form-success .t-form__inputsbox,
.js-send-form-success .t-form__submit {
display: none;
}
Работает без скриптов и без событий, и переживает любое обновление Тильды: класс — её собственный, он есть в коде и используется ей самой (в её стилях им спрятан бейдж reCAPTCHA).
Сценарий 2: переход на страницу «спасибо»
Задаётся в настройках формы полем «Страница благодарности». Одно правило, из-за которого этот переход «не работает»:
// t_forms__handleSuccess, дословный смысл:
if (callback && typeof window[callback] === 'function') {
eval(callback + '(form)'); // вызвали колбэк
} else if (successUrl) {
t_forms__handleRedirect(form, successUrl, successBox); // или перешли
}
Колбэк исключает переход. Если в настройках указана функция и она существует — переход не выполнится вообще, ни до, ни после. Никакого сообщения об этом не будет. Нужны оба — делайте переход внутри своей функции:
<!-- Блок T123. Имя функции указывается в настройках формы, поле «Callback». -->
<script>
function mkAfterSend(form) {
// Что-то своё: событие в аналитику, показ анимации, задержка.
// А переход — руками, потому что Тильда его уже не сделает.
setTimeout(function () {
window.location.href = '/thanks';
}, 1200);
}
</script>
Отдельная тонкость про существующие колбэки: на снятой странице у формы блока
корзины (t706) уже стоит data-formsended-callback="t706_onSuccessCallback" — это
код самой Тильды, который дочищает корзину. Впишете в настройках свою функцию —
замените её, и корзина после заказа останется полной. Для таких форм подходит
только событие, а не поле колбэка.
Сценарий 3: попап вместо плашки
У формы есть атрибут data-success-popup. Если он равен "y", шаг 6 идёт не в
display: block, а в window.tildaForm.showSuccessPopup() — то есть попап у Тильды
родной, и он же используется, когда форма сама живёт внутри попапа.
Открывать свой попап на событии тоже можно, и это единственный способ, если нужен свой дизайн:
<script>
document.addEventListener('tildaform:aftersuccess', function (e) {
var form = e.target;
// Имя из формы читаем ДО того, как Тильда очистит поля (шаг 8).
var nameInput = form.querySelector('[name="Name"]');
var name = nameInput ? nameInput.value.trim() : '';
// Родной бокс не показываем: он ещё не показан, шаг 6 впереди.
var box = form.querySelector('.js-successbox');
if (box) box.style.display = 'none';
// Свой попап Тильды с нужным содержимым.
if (window.tildaForm && typeof window.tildaForm.showSuccessPopup === 'function') {
window.tildaForm.showSuccessPopup(
'<div class="t-text t-text_md">Спасибо' + (name ? ', ' + name : '') + '!<br>' +
'Перезвоним в рабочие часы.</div>'
);
}
});
</script>
Обратите внимание на порядок: бокс прячется до шага 6, а не после. Прятать его позже — значит показать зелёную плашку на четверть секунды и убрать. Именно так выглядит «мигает и исчезает» в жалобах.
Почему у одних есть заголовок и кнопка, а у других нет
Успех-бокс у Тильды двух видов. Новый — три части, каждая из своего атрибута:
n.title = box.getAttribute('data-success-title') || '';
n.text = box.getAttribute('data-success-message');
n.button = box.getAttribute('data-success-btn') || '';
Старый — только текст, одной строкой. Какой из них применится, решает одна функция, и решение в ней жёсткое:
function t_forms__isNewSuccessBox(form) {
return !!form && !t_forms__isQuiz(form) && !['t396','t447','t651','t653',
't706','t708','t945','t1122'].some((c) => form.closest('.' + c));
}
То есть заголовок и кнопка в успехе не появятся:
- в квизе любого вида;
- в Zero Block (
t396) — это самый частый случай, потому что формы в Zero Block собирают все; - в блоках
t447,t651,t653,t706,t708,t945,t1122— среди них форма корзины и несколько составных блоков.
Это и есть ответ на «у коллеги та же настройка работает, а у меня нет»: настройка одна, блок разный. Обойти нельзя — проверка идёт по предку формы. Можно только собрать своё оформление на событии, как в сценарии 3.
Переменные в сообщении: имя, поля, номер заявки
В текст успеха можно писать подстановки, и это работает без единой строки кода. Формат разбирается регулярным выражением из кода Тильды:
/{{(form|tilda).([A-zА-я0-9_-]+)(?:=([^{}]+))?}}/g
Читается так:
| Что писать | Что подставится |
|---|---|
{{form.Name}} | значение поля с name="Name" |
{{form.Phone}} | значение поля Phone |
{{form.Name=клиент}} | значение, а если пусто — слово «клиент» |
{{tilda.lead_id}} | номер заявки, присвоенный сервером |
Имя после form. — это имя поля, а не его подпись. Смотреть его надо в
настройках поля, «Имя переменной». Регулярное выражение принимает и русские буквы,
поэтому {{form.Телефон}} тоже сработает, если поле так и называется.
{{tilda.lead_id}} — единственная системная переменная в этом списке, и заполняется
она на шаге 5, то есть до показа бокса. Поэтому «Ваша заявка №{{tilda.lead_id}},
запишите номер» — рабочее сообщение, а не пожелание.
Чего делать не надо: подмена до отправки
Соблазн понятный: спрятать форму сразу по нажатию кнопки, чтобы человек не нажал дважды. Так делать нельзя, и причина не в стиле, а в том, что отправка может не получиться.
Запрос уходит на сервер, и он может вернуть ошибку — не прошла валидация на стороне
Тильды, отвалилась сеть, сработала защита. Тогда Тильда добавляет форме класс
js-send-form-error, заполняет контейнеры .t-input-error и посылает
tildaform:aftererror. Если ваш код к этому моменту уже спрятал поля, человек
увидит сообщение об ошибке над пустым местом и не сможет ничего исправить.
Правильные точки — только эти:
- двойное нажатие Тильда предотвращает сама: кнопке ставится класс
t-btn_sendingи свойствоtildaSendingStatus = '1', повторный клик отбрасывается; - что-то показать — на
tildaform:aftersuccess; - что-то вернуть на место при ошибке — на
tildaform:aftererror.
Проверка за минуту на своей странице
В консоли на опубликованной странице с формой:
var form = document.querySelector('.t-form');
// 1. Какой успех-бокс применится: новый (с заголовком и кнопкой) или старый.
['t396','t447','t651','t653','t706','t708','t945','t1122']
.filter((c) => form.closest('.' + c)); // непустой список → старый, только текст
// 2. Что уже настроено в боксе.
var box = form.querySelector('.js-successbox');
[box.getAttribute('data-success-title'),
box.getAttribute('data-success-message'),
box.getAttribute('data-success-btn')];
// 3. Занято ли поле колбэка чужим кодом (у корзины — занято).
form.getAttribute('data-formsended-callback');
// 4. Посмотреть бокс, не отправляя форму.
box.style.display = 'block';
Четвёртая строка — самый быстрый способ увидеть, как сообщение выглядит в вашем дизайне: Тильда показывает бокс ровно этим же способом.
Если форма нужна не для того, чтобы что-то показать, а для того, чтобы что-то посчитать, отправить в свою систему или собрать документ, — это уже работа с формами под задачу. Проверка телефона и маска, которых Тильде не хватает, — готовый мод.