WooCommerce - Триггер валидации формы оформления заказа
Я искал ответ, но не нашел подходящего решения.
Я создаю платежный шлюз в iframe
, который загружается на странице оформления заказа. Моя цель - при нажатии на определенную кнопку вызывать функцию проверки заполнения всех обязательных полей формы. Если проверка пройдена (true
), то загружается iframe.
В противном случае должны отображаться сообщения об ошибках валидации.
Я обнаружил, что нужная функция называется update_checkout_action
и находится в классе wc_checkout_form
.
Надеюсь, информации достаточно. Если нужно что-то уточнить, дайте знать - предоставлю дополнительные детали.
Спасибо.

Я сталкивался с этим несколько раз, но пока не нашел прямого способа обработки. Вот что я делал раньше.
Вы можете легко вызвать проверку оформления заказа, имитируя клик по кнопке отправки.
$('#myButton').on('click', function(){
$('#place_order').click();
});
Однако это не очень полезно, потому что заказ просто отправится, если нет ошибок.
Есть также колбэк checkout_error, но он срабатывает только при наличии ошибки.
$(document.body).on('checkout_error', function () {
// Произошла ошибка валидации
});
Вот что нам нужно сделать.
- Определить момент нажатия кнопки отправки
- Проверить наличие ошибок
- Если есть ошибки - позволить Woo обработать их как обычно
- Если ошибок нет - предотвратить завершение заказа
- Показать ваш iframe
- ... Повторно проверить / отправить заказ
Как только кнопка отправки нажата, мы можем добавить скрытое поле и установить значение в 1. Мы можем отследить событие отправки с помощью checkout_place_order. Этот код должен быть в вашем JS-файле.
var checkout_form = $('form.woocommerce-checkout');
checkout_form.on('checkout_place_order', function () {
if ($('#confirm-order-flag').length == 0) {
checkout_form.append('<input type="hidden" id="confirm-order-flag" name="confirm-order-flag" value="1">');
}
return true;
});
Теперь добавьте функцию в functions.php, которая будет проверять это скрытое поле и останавливать заказ, если значение == 1. Заказ останавливается добавлением ошибки.
function add_fake_error($posted) {
if ($_POST['confirm-order-flag'] == "1") {
wc_add_notice( __( "custom_notice", 'fake_error' ), 'error');
}
}
add_action('woocommerce_after_checkout_validation', 'add_fake_error');
Вернемся к нашему JS-файлу. Мы можем использовать колбэк checkout_error: если есть 1 ошибка, значит, это наша фальшивая ошибка, и можно показать iframe. Если ошибок больше, значит, на странице есть реальные ошибки.
$(document.body).on('checkout_error', function () {
var error_count = $('.woocommerce-error li').length;
if (error_count == 1) { // Валидация прошла (только фальшивая ошибка)
// Показать iframe
}else{ // Валидация не прошла (есть реальные ошибки, удаляем фальшивую)
$('.woocommerce-error li').each(function(){
var error_text = $(this).text();
if (error_text == 'custom_notice'){
$(this).css('display', 'none');
}
});
}
});
В закомментированном разделе // Показать iframe я бы, вероятно, открыл его в лайтбоксе. В какой-то момент вам понадобится еще одна кнопка отправки, которая инициирует отправку формы и установит скрытое поле.
$('#confirm-order-button').click(function () {
$('#confirm-order-flag').val('');
$('#place_order').trigger('click');
});

Я нашел простое и быстрое JS-решение для своего случая (были формы WooCommerce и Stripe). Оно основано на предотвращении отправки кнопки оформления заказа, но при этом все равно выполняет проверку форм.
// создаем событие клика на динамическом элементе-обертке
$('body').on('click', 'button#place_order_wrap', function(event) {
// основной интервал, в котором происходят все действия
var validatoins = setInterval(function(){
// проверка на ошибки
if(no_errors==0){
// создаем функцию setTimeout() с ограниченным временем (например 200мс)
// чтобы ограничить функцию оформления только проверкой
setTimeout(function(){
// триггерим оригинальную кнопку
$('button#place_order').click();
// если есть ошибки, останавливаем интервал, возвращаем false
if(($('element').find('ul.woocommerce_error').length!==0)||($('element').find('.woocommerce-invalid-required-field').length!==0)){
clearInterval(validatoins);
return false;
}else{
no_errors=1;
}
}, 200);
}
if(no_errors==1){
// та же проверка ошибок
if($('#step5').find('ul.woocommerce_error').length!=0||($('#step5').find('.woocommerce-invalid-required-field').length!==0)){
// если есть ошибки, останавливаем интервал, возвращаем false
clearInterval(validatoins);
return false;
}
setTimeout(function(){
// если нет ошибок
if(($('#step5').find('ul.woocommerce_error').length==0)&&($('#step5').find('.woocommerce-invalid-required-field').length==0)){
// выполняем действия, отмечаем завершение
return false;
}
}, 1000);
// если что-то завершено
if() {
setTimeout(function(){
// триггерим оригинальный клик оформления
$('button#place_order').click();
clearInterval(validatoins);
}, 1000);
}
}
}, 1000);
}
