在验证之后但在 Woocommerce 结帐中创建订单之前挂钩
Posted
技术标签:
【中文标题】在验证之后但在 Woocommerce 结帐中创建订单之前挂钩【英文标题】:Hooking After Validation but Before Order Create in Woocommerce Checkout 【发布时间】:2019-03-14 13:30:46 【问题描述】:我正在尝试在结帐中创建一个步骤来确认您的订单。我在想,当点击下单按钮并且结帐字段有效时,我可以运行一些 JS 来显示模式或其他内容。
是否有类似 checkout_place_order 的 JS 触发器/事件在验证后运行?例如,我可以使用以下内容,但它发生在验证之前。也许有一种方法可以从内部触发验证并据此显示我的模式?
var checkout_form = $('form.checkout');
checkout_form.on('checkout_place_order', function ()
// do your custom stuff
return true; // continue to validation and place order
return false; // doesn't validate or place order
);
还有 woocommerce_after_checkout_validation 钩子,但我不知道如何利用它来实现我所追求的。
我对想法持开放态度...
【问题讨论】:
【参考方案1】:我终于能够弄清楚这一点,它更像是一种解决方法,因为我认为没有明确的方法可以做到这一点。
单击“下订单”按钮后,我们使用 checkout_place_order 事件放置一个隐藏字段,其值设置为 1。
var checkout_form = $('form.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;
);
接下来,我们使用钩子 woocommerce_after_checkout_validation 来检查我们隐藏的输入,如果值为 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');
最后,我们使用 checkout_error 事件来确定是否有真正的验证,或者如果只有 1 个错误,我们添加的错误。如果只有 1 个错误,则表示验证通过,因此我们可以显示我们的模式(或您需要做的任何事情)。
$(document.body).on('checkout_error', function ()
var error_count = $('.woocommerce-error li').length;
if (error_count == 1) // Validation Passed (Just the Fake Error I Created Exists)
// Show Confirmation Modal or Whatever
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');
);
);
在我的模式中,我有一个确认按钮,它将我们的隐藏字段值设置为空,然后再次单击下订单按钮。这次订单将通过,因为我们正在检查隐藏的输入值 1。
$('#confirm-order-button').click(function ()
$('#confirm-order-flag').val('');
$('#place_order').trigger('click');
);
【讨论】:
【参考方案2】:据我所知,验证和订单创建过程之间没有任何挂钩,这将允许您与客户互动,进行一些操作。
使用 jQuery 和 Sweet Alert 组件 (SWAL 2),下面是一个代码示例,它将禁用显示带有确认按钮的 Sweet Alert 的“Place Order”按钮。它并不完美,但它部分回答了您的问题。
一旦客户确认,“Place Order”按钮将被启用并由代码触发...如果客户使用取消按钮,Checkout review order 将被刷新(Ajax)。
代码:
add_action( 'wp_footer', 'checkout_place_order_script' );
function checkout_place_order_script()
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// jQuery code start below
?>
<script src="https://unpkg.com/sweetalert2@8.8.1/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/promise-polyfill@8.1.0/dist/polyfill.min.js"></script>
jQuery( function($)
var fc = 'form.checkout',
pl = 'button[type="submit"][name="woocommerce_checkout_place_order"]';
$(fc).on( 'click', pl, function(e)
e.preventDefault(); // Disable "Place Order" button
// Sweet alert 2
swal(
title: 'Are you sure?',
text: "You are about proceed the order",
type: 'success',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: "Yes let's go!"
).then((result) =>
if (result.value)
$(fc).off(); // Enable back "Place Order button
$(pl).trigger('click'); // Trigger submit
else
$('body').trigger('update_checkout'); // Refresh "Checkout review"
);
);
);
</script>
<?php
endif;
代码进入您的活动子主题(或活动主题)的 function.php 文件中。经过测试并且可以工作。
【讨论】:
我不太喜欢使用该警报框,但您的示例的主要问题是它不会在验证后发生,因此如果出现错误,它会带来尴尬的体验。跨度> 您知道只有在表单有效后才能运行的方法吗?还是触发验证运行的方法?【参考方案3】:我迟到了,但想分享上述答案的变体
jQuery(document).ready(function($)
/* on submit */
$('form#FORMID').submit( function(e)
/* stop submit */
e.preventDefault();
/* count validation errors */
var error_count = $('.woocommerce-error li').length;
/* see if terms and conditions are accepted */
var terms = $('input#terms').is(':checked');
/* if there are no validation errors and terms are accepted*/
if( error_count == 0 && terms )
/* trigger confirmation dialogue */
if( confirm('Are you sure?') )
/* resume default submit */
$(this).unbind('submit').submit();
else
/* do nothing */
e.stopPropagation();
);
);
【讨论】:
【参考方案4】:在这种情况下,我为自己做出了一个快速而简单的 JS 决策(有 woocommerce 和条带形式)。这是基于阻止结帐按钮提交但仍会进行表单验证。
// 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);
【讨论】:
以上是关于在验证之后但在 Woocommerce 结帐中创建订单之前挂钩的主要内容,如果未能解决你的问题,请参考以下文章