Изменение значения поля ввода Contact Form 7 перед отправкой

23 июн. 2018 г., 19:45:02
Просмотры: 28.8K
Голосов: 1

Я использую Contact Form 7 и Flamingo для создания формы регистрации консультантов на моем сайте WordPress. По требованию клиента, каждая отправка должна содержать регистрационный код (reg_code), который представляет собой комбинацию даты отправки и случайного числа для обеспечения уникальности.

Я добавил скрытое поле ввода в код CF7 с идентификатором "reg_code". В первой попытке я использовал JavaScript для генерации переменной "reg_code" сразу после посещения пользователем сайта и установки значения скрытого поля в сгенерированную переменную "reg_code". Код успешно сохранялся при отправке CF7, но в некоторых случаях, когда пользователь не отправлял форму при первом посещении, а через несколько дней, часть даты в его "reg_code" оказывалась неверной, так как код был сгенерирован при первом посещении и кэширован в браузере.

Чтобы избежать этой проблемы, я решил перенести функцию генерации "reg_code" из JavaScript в PHP, и процедура должна быть следующей:

  1. Нажатие кнопки отправки
  2. Использование AJAX для вызова PHP-функции, которая возвращает reg_code
  3. Установка значения скрытого поля "reg_code" в CF7 равным полученному результату
  4. Выполнение отправки 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, чтобы изменить значение поля ввода, а затем продолжить процесс отправки?

Большое спасибо

2
Комментарии

Не уверен, уведомляет ли система о редактировании ответов, поэтому просто сообщаю, что я добавил метод, который должен позволить вам добавить свой собственный тег CF7 без использования дополнительного плагина. Я не тестировал его, но код довольно простой.

Andy Macaulay-Brook Andy Macaulay-Brook
23 июн. 2018 г. 23:40:21

Можно ли использовать что-то подобное для автоматической нумерации заявок, чтобы каждая новая заявка получала номер +1?

Mitja Mitja
28 февр. 2020 г. 10:50:48
Все ответы на вопрос 2
0

Хочу подключиться к обсуждению, так как сам недавно столкнулся с аналогичной проблемой - необходимостью модифицировать поля ввода перед отправкой формы 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.

Я еще не проверял, но предполагаю, что используя evt.preventDefault(), можно было бы полностью отменить отправку формы через CF7 Ajax, если это необходимо. Проверено 22.04.2019 - не работает.

21 апр. 2020 г. 22:19:21
1

Вы можете избежать проблем с 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();
}
23 июн. 2018 г. 20:56:22
Комментарии

Без проблем. Спасибо - вы подтолкнули меня наконец разобраться, как кодировать свои собственные теги CF7, и я добавлю это как правку к этому ответу.

Andy Macaulay-Brook Andy Macaulay-Brook
23 июн. 2018 г. 21:19:47