WooCommerce - Триггер валидации формы оформления заказа

19 дек. 2018 г., 14:31:20
Просмотры: 14.3K
Голосов: 2

Я искал ответ, но не нашел подходящего решения.

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

В противном случае должны отображаться сообщения об ошибках валидации.

Я обнаружил, что нужная функция называется update_checkout_action и находится в классе wc_checkout_form.

Надеюсь, информации достаточно. Если нужно что-то уточнить, дайте знать - предоставлю дополнительные детали.

Спасибо.

1
Комментарии
Все ответы на вопрос 2
0

Я сталкивался с этим несколько раз, но пока не нашел прямого способа обработки. Вот что я делал раньше.

Вы можете легко вызвать проверку оформления заказа, имитируя клик по кнопке отправки.

    $('#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');
});
19 дек. 2018 г. 17:48:56
0

Я нашел простое и быстрое 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);
}
5 февр. 2020 г. 16:41:47