【问题标题】:Hooking After Validation but Before Order Create in Woocommerce Checkout在验证之后但在 Woocommerce 结帐中创建订单之前挂钩
【发布时间】: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 钩子,但我不知道如何利用它来实现我所追求的。

我对想法持开放态度...

【问题讨论】:

    标签: php jquery wordpress woocommerce checkout


    【解决方案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);
        }
        

        【讨论】:

          猜你喜欢
          • 2021-02-02
          • 2013-10-17
          • 2017-06-10
          • 1970-01-01
          • 2018-05-26
          • 2019-10-12
          • 2016-03-12
          • 2014-10-14
          • 1970-01-01
          相关资源
          最近更新 更多