#javascript #jquery #ajax #wordpress #fetch
#javascript #jquery #ajax #wordpress #выборка
Вопрос:
Я работаю над сайтом WordPress и пытаюсь преобразовать свой код jQuery в ванильный JavaScript (в основном для обучения, но также и для того, чтобы мне не приходилось полагаться на jQuery). Цель состоит в том, чтобы после отправки формы вместо перехода на страницу благодарности или что-то еще просто отобразить наложение поверх формы с надписью «Спасибо за ваше сообщение». Опять же, все отлично работает с jQuery / AJAX, но я хочу попробовать заставить его работать и с обычным JavaScript.
Вот рабочий код jQuery:
jQuery('#myContactForm').on('submit', function () {
var formData = jQuery(this).serializeArray();
formData.push({
name: 'security',
value: ajaxNonce
});
jQuery.ajax({
type: 'POST',
url: ajaxUrl,
data: formData
});
jQuery('.form-overlay').addClass('visible');
return false;
});
И вот рабочий код из functions.php:
<?php
function javascript_variables() { ?>
<script type="text/javascript">
var ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>';
var ajaxNonce = '<?php echo wp_create_nonce('secure_nonce_name'); ?>';
</script>
<?php
}
add_action('wp_head', 'javascript_variables');
add_action('wp_ajax_send_form', 'send_form');
add_action('wp_ajax_nopriv_send_form', 'send_form');
function send_form() {
check_ajax_referer('secure_nonce_name', 'security');
$to = 'myemailaddressgoeshere@gmail.com';
$subject = $_POST['subject'];
$body = 'From: ' . $_POST['full_name'] . '<br />';
$body .= 'Email: ' . $_POST['email'] . '<br />';
$body .= 'Phone: ' . $_POST['phone'] . '<br />';
$body .= 'Message: ' . $_POST['message'] . '<br />';
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail($to, $subject, $body, $headers);
wp_die();
}
И, наконец, вот соответствующий ввод внутри формы:
<input class="form-inputs" type="hidden" name="action" value="send_form" />
Вот что я придумал, пытаясь использовать Fetch API вместо jQuery:
// handle form submission
const formSubmissionHandler = () => {
const form = document.getElementById('myContactForm');
const formOverlay = document.querySelector('.form-overlay');
const formInputs = Array.from(document.querySelectorAll('.form-inputs'));
const formData = [];
form.addEventListener('submit', (e) => {
e.preventDefault();
formInputs.forEach((input) => {
if (!input.name || !input.value) {
return;
}
formData.push({
name: input.name,
value: input.value,
});
});
formData.push({
name: 'security',
value: ajaxNonce,
});
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
};
// send post request
fetch(ajaxUrl, fetchOptions)
.then((res) => res.json())
.then((res) => console.log(res))
.catch((err) => console.error(err));
formOverlay.classList.add('visible');
});
};
document.addEventListener('DOMContentLoaded', formSubmissionHandler);
Я наткнулся на FormData()
конструктор из поиска, не уверен, где / буду ли я использовать его здесь?
И вот что я написал в своем functions.php файл:
function send_form() {
check_ajax_referer('secure_nonce_name', 'security');
$to = 'myemailaddressgoeshere@gmail.com';
$subject = $_POST['subject'];
$json_input = json_decode(file_get_contents('php://input'), true);
$body = '';
foreach ($json_input as $key => $value) {
$body = 'From: ' . $value['full_name'] . '<br />';
$body .= 'Email: ' . $value['email'] . '<br />';
$body .= 'Phone: ' . $value['phone'] . '<br />';
$body .= 'Message: ' . $value['message'] . '<br />';
}
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail($to, $subject, $body, $headers);
wp_die();
}
Я новичок во всем этом, поэтому, если бы кто-нибудь мог мне помочь, я был бы очень признателен. Я думаю, что моя проблема в том, как я анализирую данные JSON в functions.php . Или я мог просто не форматировать данные так же в vanilla JS, как это делается в jQuery? Спасибо!
Комментарии:
1. Подлинный вопрос из любопытства: почему вы используете CSS, чтобы «скрыть» ваше уже скрытое
action
поле ввода?2. Также обратите внимание, что
formInputs
(в вашем ванильном JS-коде) запрашивается только для элементов с classform-inputs
. Это не учитывает ваше скрытоеaction
поле, верно? Ваша версия jQuery заполняет все поля.3. @cabrerahector Я забыл включить имя класса form-inputs в скрытый ввод, когда вставлял код. С тех пор я обновил его. А для CSS на скрытом вводе, tbh, я не уверен, ха-ха. Я получил большую часть кода из других статей / руководств, поэтому я этого не заметил. С тех пор я удалил его.
4. не могли бы вы
console.log(ajaxUrl)
раньшеfetch(ajaxUrl, fetchOptions)
и сообщить мне, получили ли вы правильный URL? Один из 400 триггеров ошибок при неправильном запросе — неверный URL.5. @parse
console.log(ajaxUrl)
, когда я получаюhttp://www.domainnamehere.ca/wp-admin/admin-ajax.php
Ответ №1:
Я знаю, что мне, вероятно, немного поздно публиковать это, но если кто-то в будущем столкнется с этим, вот в чем дело:
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
};
здесь вы создаете строку json для передачи целевому URL-адресу, но вы должны помнить, что синтаксический анализатор ajax WordPress не может понимать данные, отправляемые ему в виде необработанного json.
$json_input = json_decode(file_get_contents('php://input'), true);
здесь вы превращаете необработанные входные данные, которые вы получили, в массив, но до этого все, что получил WordPress, было частью данных, которая представляет собой простую строку. Таким образом, он не знает, как с этим бороться и какие пользовательские хук и действия должны быть запущены для проверки этого.
add_action('wp_ajax_send_form', 'send_form');
add_action('wp_ajax_nopriv_send_form', 'send_form');
здесь вы сообщаете wordpress ожидать некоторый запрос с именем действия ‘send_form’, и если вы его получили, передайте его в функцию с именем ‘send_form’. Однако WordPress не получает этот запрос с именем «действие». Отсюда и ошибка.
Однако исправление довольно простое, просто добавьте это имя запроса в качестве GET к URL, на который вы отправляете необработанные данные, и очистите его для wordpress:
var ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>?action=send_for';
или версия, которую я предпочитаю:
// send post request
fetch(ajaxUrl '?action=send_form', fetchOptions)
.then((res) => res.json())
.then((res) => console.log(res))
.catch((err) => console.error(err));
и готово!
Я думаю, что как только вы начнете работать с fetch () и WP, по крайней мере, на данный момент (пока WordPress не найдет способ), это может пригодиться.