☰
ELEMENTOR / PRACTICE

Как защитить форму Elementor от двойной отправки

Как защитить форму Elementor от двойной отправки

Двойная отправка формы Elementor происходит, когда пользователь повторно нажимает кнопку до завершения запроса. Это особенно часто случается на смартфонах, при медленном интернет-соединении или отсутствии мгновенной визуальной обратной связи после первого нажатия.

В результате CRM, почтовая система или система обработки заказов могут получить две одинаковые заявки. Один из простых способов снизить этот риск — после первого корректного нажатия заблокировать кнопку и показать статус «Отправка…». Ниже приведён вариант для Elementor Pro, а также важные проверки валидации и обработки ошибок.

Почему форма отправляется дважды

Кнопка формы не всегда блокируется автоматически. Если ответ сервера задерживается, пользователь может нажать её несколько раз. Каждое нажатие способно создать отдельный запрос к обработчику формы.

Проблема может проявляться не только в виде двух писем. Дубли попадают в CRM, создают повторные заказы, запускают несколько автоматических сценариев или приводят к повторному списанию средств, если форма связана с оплатой.

  • медленная загрузка или нестабильное мобильное соединение;
  • отсутствие изменения состояния кнопки после нажатия;
  • двойное нажатие из-за задержки ответа;
  • повторная отправка после обновления страницы или возврата на неё с помощью кнопки браузера «Назад».

Как подготовить кнопку формы в Elementor

Сначала откройте страницу с нужной формой в редакторе Elementor Pro. В виджете Form найдите настройки кнопки отправки и добавьте ей следующий CSS-класс без точки в начале:

  • prevent-double-submit

Где указать класс

Добавьте класс в поле CSS Classes в расширенных настройках кнопки. Не вставляйте в это поле JavaScript и не добавляйте символ «.» — он используется только в CSS-селекторах и коде.

Если на странице несколько форм, класс можно добавить только к тем кнопкам, которым нужна защита. Это позволит не изменять поведение остальных форм.

JavaScript для блокировки повторной отправки

Добавьте код в Custom Code или в JavaScript-файл дочерней темы. Если используется Custom Code, разместите скрипт в футере или в другом месте, где он загрузится после основного содержимого страницы.

Скрипт работает именно с формой Elementor и кнопкой с классом prevent-double-submit. После первой отправки он запоминает состояние кнопки, отключает её и изменяет надпись. Если Elementor сообщает об успешной отправке или AJAX-ошибке, кнопка возвращается в исходное состояние.

document.addEventListener('submit', function (event) {
  const form = event.target.closest('.elementor-form');
  if (!form) return;

  const button = form.querySelector(
    '.prevent-double-submit[type="submit"]'
  );
  if (!button) return;

  if (button.dataset.submitted === 'true') {
    event.preventDefault();
    return;
  }

  button.dataset.submitted = 'true';
  button.dataset.originalLabel = button.tagName === 'INPUT'
    ? button.value
    : button.textContent;

  button.disabled = true;

  if (button.tagName === 'INPUT') {
    button.value = 'Надсилання…';
  } else {
    button.textContent = 'Надсилання…';
  }
}, true);

function resetSubmitButton(form) {
  if (!form || !form.matches('.elementor-form')) return;

  const button = form.querySelector(
    '.prevent-double-submit[type="submit"]'
  );
  if (!button) return;

  button.disabled = false;
  button.dataset.submitted = 'false';

  if (button.dataset.originalLabel) {
    if (button.tagName === 'INPUT') {
      button.value = button.dataset.originalLabel;
    } else {
      button.textContent = button.dataset.originalLabel;
    }
  }
}

if (window.jQuery) {
  jQuery(document).on('submit_success submit_error', function (event) {
    const form = event.target.closest
      ? event.target.closest('.elementor-form')
      : null;

    resetSubmitButton(form);
  });
}

Что делает этот код

Свойство data-submitted работает как внутренний флаг. После первой отправки оно получает значение true, поэтому следующая попытка блокируется с помощью event.preventDefault(). Свойство disabled дополнительно не позволяет нажать кнопку мышью или пальцем.

Исходная надпись сохраняется до её изменения. Это важно, поскольку после ошибки пользователь должен увидеть обычный текст кнопки, а не оставаться со статусом «Отправка…».

Что происходит при ошибке валидации

Если поле не заполнено или не соответствует правилам валидации браузера, событие submit обычно не запускается. В этом случае кнопка не успевает заблокироваться, поэтому пользователь может исправить данные и повторить попытку.

Другая ситуация возникает, когда Elementor или сервер возвращает ошибку уже после начала AJAX-запроса. Именно поэтому в коде предусмотрена обработка событий submit_success и submit_error. После ошибки кнопка снова активируется, а её исходный текст восстанавливается.

После установки скрипта обязательно проверьте не только успешную заявку, но и пустые обязательные поля, некорректный email и серверную ошибку. Если на сайте используется дополнительный плагин валидации, у него может быть собственное событие для сброса состояния кнопки.

  • нажмите кнопку в пустой форме;
  • введите некорректный email-адрес;
  • исправьте ошибку и повторите отправку;
  • убедитесь, что после неудачной AJAX-отправки кнопку можно нажать ещё раз.

Как проверить защиту на реальном сайте

Тестируйте форму не только в редакторе Elementor, но и на опубликованной странице. Лучше всего выполнить проверку в режиме инкогнито и на мобильном устройстве, где задержка между нажатием и ответом сервера заметнее.

После нажатия быстро нажмите кнопку ещё несколько раз. В почтовом ящике, CRM или другой системе приёма заявок должна появиться только одна запись. Если у формы есть интеграция с вебхуком, проверьте также журнал полученных запросов.

После добавления скрипта очистите кеш. Плагин кеширования, CDN или оптимизатор JavaScript могут отдавать старую версию страницы или изменить порядок выполнения скриптов.

  • проверьте страницу на телефоне и компьютере;
  • убедитесь, что текст кнопки меняется сразу;
  • проверьте наличие одной записи в почте, CRM или базе данных;
  • посмотрите, есть ли ошибки JavaScript в консоли браузера;
  • повторите тест после очистки кеша.

Распространённые ошибки и важные ограничения

Не добавляйте класс к самой форме, если скрипт ожидает его на кнопке. Также не используйте селектор для всех кнопок Elementor на странице: это может случайно заблокировать кнопки меню, попапов или других виджетов.

Защита кнопки снижает количество случайных дублей, но не обеспечивает полной идемпотентности операции. Пользователь может обновить страницу, повторить запрос после сбоя сети или отправить те же данные с другого устройства.

Для заказов, платежей и заявок, связанных с финансовыми последствиями, стоит дополнительно реализовать защиту на сервере: проверку уникального идентификатора заявки, контроль повторных webhook-запросов или фильтрацию одинаковых записей в CRM. Клиентский JavaScript не может заменить серверную проверку.

  • не вставляйте скрипт несколько раз на одну страницу;
  • не удаляйте обработку submit_error, если форма работает через AJAX;
  • не считайте отключённую кнопку защитой от повторной оплаты;
  • проверяйте совместимость с плагинами кеширования и оптимизации JavaScript.

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

Работает ли этот способ с бесплатной версией Elementor?

Код рассчитан на виджет Form в Elementor Pro, поскольку он использует класс elementor-form и соответствующую логику отправки. У сторонних форм селекторы и события могут отличаться.

Можно ли заблокировать кнопку без JavaScript?

Надёжно реализовать блокировку после первого нажатия без JavaScript обычно не получится. CSS может изменить внешний вид кнопки, но не останавливает повторную отправку формы.

Что делать, если кнопка остаётся заблокированной после ошибки?

Проверьте, действительно ли форма создаёт событие submit_error, нет ли ошибки в консоли браузера и не загружается ли jQuery в конфликтующем режиме. Также убедитесь, что класс добавлен именно кнопке с type="submit".

Защищает ли скрипт от повторной отправки после обновления страницы?

Нет. Состояние кнопки сохраняется только в течение текущей загрузки страницы. Для критически важных операций нужна дополнительная серверная проверка уникальности заявки или транзакции.

Вывод

Для большинства форм Elementor достаточно добавить к кнопке класс prevent-double-submit и подключить JavaScript, который блокирует её после первой отправки. Важно не оставлять кнопку заблокированной после ошибки, поэтому сценарий нужно проверить вместе с валидацией и AJAX-ответами.

Если форма создаёт заказ, платёж или запись в CRM, сочетайте клиентскую защиту с серверной проверкой дублей. Это позволит устранить не только проблему двойного нажатия, но и другие способы повторного создания заявки.

← Все материалы Elementor