2

I have been looking around for the answer but did not find any.

I am creating an iframe payment gateway while the iframe is loaded inside the checkout page. My goal is once the customer clicks on a certain button, the function which validates that the customer has filled all the required input is triggered and if it returns true the iframe loads.

Otherwise, the notice from the validating function is triggered.

I found the function as a method called update_checkout_action inside the wc_checkout_form class.

Hope it's enough information, if needed any more, please let me know and I'll provide.

Thanks.

1

2 Answers 2

4

I ran into this a few times, I have yet to find a straight forward method of handling it. But here is what I've done in the past.

You can trigger checkout validation easily by forcing a click on the submit button.

    $('#myButton').on('click', function(){
        $('#place_order').click();
    });

However, this isn't really useful for you because it will just submit the order if there are no errors.

There is also the checkout_error callback, but it only fires if there is a error.

    $(document.body).on('checkout_error', function () {
        // There was a validation error
    });

Here is what we need to do.

  • Detect when the submit button is clicked
  • Check for errors
  • If there are errors let Woo handle them as normal
  • If there are No errors, stop the order from completing
  • Show your iframe
  • ... Re-Validate / Re-submit Order


As soon as the submit button is clicked, we can add a hidden field and set the value to 1. We can detect the submit event by using checkout_place_order. This should go in your JS file.

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;
});

Now, add a function to functions.php that will check that hidden input and stop the order if the value == 1. It stops the order by adding an error.

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');

Back in our JS file, we can use the checkout_error callback, if it has 1 error we know it was the fake error we created so we can show the iframe. If it has more than 1 error it means there are other real errors on the page.

$(document.body).on('checkout_error', function () {
    var error_count = $('.woocommerce-error li').length;

    if (error_count == 1) { // Validation Passed (Just the Fake Error Exists)
        // Show iFrame
    }else{ // Validation Failed (Real Errors Exists, Remove the Fake One)
        $('.woocommerce-error li').each(function(){
            var error_text = $(this).text();
            if (error_text == 'custom_notice'){
                $(this).css('display', 'none');
            }
        });
    }
});

In the commented out section, // Show iFrame, I would probably open in it in a lightbox. At some point you will need another submit button that triggers the form submit and set the hidden input.

$('#confirm-order-button').click(function () {
    $('#confirm-order-flag').val('');
    $('#place_order').trigger('click');
});
0

I got a fast and simple JS decision for myself in this case (there were woocommerce and stripe forms). That is based on preventing the checkout button from submit but still makes forms verifications.

// making the wrap click event on dinamic element

$('body').on('click', 'button#place_order_wrap', function(event) { 

    // main interval where all things will be 

    var validatoins = setInterval(function(){ happen

        // checking for errors

        if(no_errors==0){ 

        // making the setTimeout() function with limited time like 200ms 
        // to limit checkout function for just make verification

        setTimeout(function(){ 

            // triggering original button

            $('button#place_order').click(); 

            // if there some errors, stop the interval, return 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){    

            // same error checking

            if($('#step5').find('ul.woocommerce_error').length!=0||($('#step5').find('.woocommerce-invalid-required-field').length!==0)){ 

                // if there some errors, stop the interval, return false

                clearInterval(validatoins);
                return false; 
            }


            setTimeout(function(){

                // if no errors

                if(($('#step5').find('ul.woocommerce_error').length==0)&&($('#step5').find('.woocommerce-invalid-required-field').length==0)){ 

                    // do something, mark that finished

                    return false;
                }
            }, 1000);


            // if something finished

            if() {

                setTimeout(function(){

                    // trigger original checkout click

                    $('button#place_order').click(); 
                    clearInterval(validatoins);
                }, 1000);

            }

        }

    }, 1000);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.