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