Изменение значения поля ввода Contact Form 7 перед отправкой
Я использую Contact Form 7 и Flamingo для создания формы регистрации консультантов на моем сайте WordPress. По требованию клиента, каждая отправка должна содержать регистрационный код (reg_code), который представляет собой комбинацию даты отправки и случайного числа для обеспечения уникальности.
Я добавил скрытое поле ввода в код CF7 с идентификатором "reg_code". В первой попытке я использовал JavaScript для генерации переменной "reg_code" сразу после посещения пользователем сайта и установки значения скрытого поля в сгенерированную переменную "reg_code". Код успешно сохранялся при отправке CF7, но в некоторых случаях, когда пользователь не отправлял форму при первом посещении, а через несколько дней, часть даты в его "reg_code" оказывалась неверной, так как код был сгенерирован при первом посещении и кэширован в браузере.
Чтобы избежать этой проблемы, я решил перенести функцию генерации "reg_code" из JavaScript в PHP, и процедура должна быть следующей:
- Нажатие кнопки отправки
- Использование AJAX для вызова PHP-функции, которая возвращает reg_code
- Установка значения скрытого поля "reg_code" в CF7 равным полученному результату
- Выполнение отправки CF7, которая сохраняет все поля CF7 в Flamingo
Вот мой JavaScript для вызова AJAX перед событием отправки CF7:
$('.wpcf7-form').on('submit', function (e) {
$.ajax({
type: "post",
dataType: "json",
url: js_object.ajax_url,
data: {
action: "custom_reg_code",
},
success: function (response) {
if (response.success) {
$('#reg_code').val(response.data)
}
else {
console.log('Что-то пошло не так')
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('ошибка: ' + textStatus, errorThrown);
},
complete: function() {
}
})
})
Мой результат: Работает только иногда. Только некоторые отправки имеют значение "reg_code", другие имеют пустой "reg_code".
Как я предполагаю, событие отправки CF7 не ждет завершения AJAX-вызова. Я пробовал добавить e.preventDefault() в код выше, чтобы остановить стандартную отправку CF7, но безуспешно. Я также пробовал слушатель событий CF7 "wpcf7submit", но тоже безрезультатно.
Итак, вопрос: Есть ли способ приостановить стандартное событие отправки CF7, чтобы изменить значение поля ввода, а затем продолжить процесс отправки?
Большое спасибо

Хочу подключиться к обсуждению, так как сам недавно столкнулся с аналогичной проблемой - необходимостью модифицировать поля ввода перед отправкой формы CF7 через ajax. Похоже, автор изначально пытался решить эту задачу через JavaScript, что не было затронуто в ответе Энди. Вот пример, как это можно сделать:
var form = document.getElementsByClassName('wpcf7-form')[0];
form.addEventListener('submit', function(evt) {
form.elements['reg_code'].value = 'parsed_code';
}, { capture: true });
Обратите особое внимание на последний аргумент в обработчике событий - useCapture = true
. По умолчанию этот параметр имеет значение false. В моей первоначальной версии кода, которая не работала, этот аргумент не учитывался. Ajax-отправка CF7 всегда срабатывала первой, игнорируя мое событие. Простое изменение useCapture на true позволяет вашему событию сработать до отправки формы через CF7 Ajax.
Я еще не проверял, но предполагаю, что используя Проверено 22.04.2019 - не работает.evt.preventDefault()
, можно было бы полностью отменить отправку формы через CF7 Ajax, если это необходимо.

Вы можете избежать проблем с AJAX и пойти другим путём, добавив скрытое поле в вашу форму на PHP.
Метод 1, с использованием плагина
Я обычно использую плагин Contact Form 7 Dynamic Text Extension как простой способ создания пользовательских тегов для CF7, хотя это всё равно требует небольшого кодинга. Вы также можете пойти дальше и просто закодировать свои собственные теги CF7, но я пока не пробовал это — возможно, добавлю такой вариант позже как дополнение к ответу.
С этим плагином вы можете добавить теги в вашу форму CF7 следующим образом:
[dynamichidden custom-reg-code “CF7_custom_reg_code”]
А в разделе отправки email в админке CF7 вы вставляете [custom-reg-code].
Чтобы это заработало, просто создайте соответствующий шорткод для генерации строки:
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x='0123456789', ceil($length/strlen($x)) )),1,$length);
}
function wpse306816_CF7_custom_reg_code() {
return date("Ymd") . generateRandomString();
}
add_shortcode('CF7_custom_reg_code', 'wpse306816_CF7_custom_reg_code');
Спасибо https://stackoverflow.com/a/13212994/6347850 за код генерации случайного числа.
Теперь в вашей форме будет скрытое поле, состоящее из текущей даты и случайного числа, которое можно использовать в отправляемом email или сохранить в Flamingo, как и любое другое поле CF7.
Метод 2, без использования плагина
Немного исследований показали, что ещё проще создать собственный тег CF7 и не заморачиваться с плагином.
Чтобы создать тег CF7 [serial]
, вы регистрируете его с помощью wpcf7_add_form_tag()
на хуке wpcf7_init
, передавая имя тега и название callback-функции для его обработки:
add_action( 'wpcf7_init', 'wpse306816_CF7_add_custom_tag' );
function wpse306816_CF7_add_custom_tag() {
wpcf7_add_form_tag(
'serial',
'wpse306816_CF7_handle_custom_tag' );
}
А в вашем случае callback-функции достаточно просто вернуть строку с серийным номером:
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x='0123456789', ceil($length/strlen($x)) )),1,$length);
}
function wpse306816_CF7_handle_custom_tag( $tag ) {
return date("Ymd") . generateRandomString();
}
