根据 Woocommerce 3 中的运输方式显示或隐藏结帐字段

Posted

技术标签:

【中文标题】根据 Woocommerce 3 中的运输方式显示或隐藏结帐字段【英文标题】:Show or hide checkout fields based on shipping method in Woocommerce 3 【发布时间】:2018-03-19 22:25:43 【问题描述】:

我正在尝试根据送货方式隐藏结帐字段。

function premove_billing_checkout_fields($fields) 
    global $woocommerce;
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = $chosen_methods[0];

    if( $chosen_shipping === 'local_pickup:20' ) 
       unset($fields['billing']['billing_postcode']);
       unset($fields['billing']['billing_state']);
       unset($fields['billing']['billing_country']);
    

    if( $chosen_shipping === 'wc_custom_shipping_pickpoint' ) 
       unset($fields['billing']['billing_postcode']);
       unset($fields['billing']['billing_address_1']);
       unset($fields['billing']['billing_state']);
    
    return $fields;

add_filter('woocommerce_checkout_fields', 
'premove_billing_checkout_fields', 990 );

此代码有效,但要隐藏我需要刷新页面的字段。 如何使用 Ajax 隐藏字段?

【问题讨论】:

我试图在搜索中找到我的问题的答案,但没有具体找到。 PickPoint 是送货服务之一。如果您设法隐藏 local_pickup 的字段,那么对于pickpoint,我可以类推。通过 ID,我一般不会隐藏字段。 ID local_pickup:20 是“shipping_method_0_local_pickup20” ID wc_custom_shipping_pickpoint 是“shipping_method_0_wc_custom_shipping_pickpoint” 这是一个关于那个问题的问题,但没有人回答。 ***.com/questions/46195765/… 【参考方案1】:

更新 4 (2018 年 6 月发布) - 添加了专门针对 Woocommerce 3.4.x 的初始化延迟。 - 解决了启用送货地址复选框时的错误。 - 增强了更轻更有效的 jQuery 代码。 - 添加条件字段验证

您不需要任何 Ajax 来实现这一点。第一个功能将使所有必要的结帐字段都不是“必需的”,因为这是能够有条件地显示/隐藏结帐字段所必需的。第二个功能(主要是 jQuery)将根据选择的运输方式显示/隐藏您想要的字段。

// Conditional Show hide checkout fields based on chosen shipping methods
add_action( 'wp_footer', 'custom_checkout_field_script' );
function custom_checkout_field_script() 

    // HERE your shipping methods rate IDs
    $local_pickup = 'local_pickup:20';
    $pickpoint = 'wc_custom_shipping_pickpoint';

    $required_text = esc_attr__( 'required', 'woocommerce' );
    $required_html = '<abbr class="required" title="' . $required_text . '">*</abbr>';
    ?>
    <script>
        jQuery(function($)
            var ism = 'input[name^="shipping_method"]',         ismc = ism+':checked',
                csa = 'input#ship-to-different-address-checkbox',
                rq = '-required',       vr = 'validate'+rq,     w = 'woocommerce',      wv = w+'-validated',
                iv = '-invalid',        fi = '-field',          wir = w+iv+' '+w+iv+rq+fi,
                b = '#billing_',        s = '#shipping_',       f = '_field',
                a1 = 'country',     a2 = 'address_1',   a3 = 'address_2',   a4 = 'postcode',    a5 = 'state',
                b1 = b+a1+f,        b2 = b+a2+f,        b3 = b+a3+f,        b4 = b+a4+f,        b5 = b+a5+f,
                s1 = s+a1+f,        s2 = s+a2+f,        s3 = s+a3+f,        s4 = s+a4+f,        s5 = s+a5+f,
                pickPoint = '<?php echo $pickpoint; ?>',        localPickup = '<?php echo $local_pickup; ?>';

            // Utility function to shows or hide checkout fields
            function showHide( action='show', selector='' )
                if( action == 'show' )
                    $(selector).show(function()
                        $(this).addClass(vr);
                        $(this).removeClass(wv);
                        $(this).removeClass(wir);
                        if( $(selector+' > label > abbr').html() == undefined )
                            $(selector+' label').append('<?php echo $required_html; ?>');
                    );
                else
                    $(selector).hide(function()
                        $(this).removeClass(vr);
                        $(this).removeClass(wv);
                        $(this).removeClass(wir);
                        if( $(selector+' > label > abbr').html() != undefined )
                            $(selector+' label > .required').remove();
                    );
            

            // Initializing at start after checkout init (Based on the chosen shipping method)
            setTimeout(function()
                if( $(ismc).val() == pickPoint ) // Chosen "Pick point" (Hiding "Delivery")
                
                    showHide('show',b1 ); // Country
                    showHide('hide',b2 ); // Address 1
                    showHide('hide',b3 ); // Address 2
                    showHide('hide',b4 ); // Postcode
                    showHide('hide',b5 ); // State
                
                else if( $(ismc).val() == localPickup ) // Choosen "Local pickup" (Hidding "Take away")
                
                    showHide('hide',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('hide',b4);
                    showHide('hide',b5);
                
                else
                
                    showHide('show',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('show',b4);
                    showHide('show',b5);
                
            , 100);

            // When shipping method is changed (Live event)
            $( 'form.checkout' ).on( 'change', ism, function() 
                if( $(ismc).val() == pickPoint )
                
                    showHide('show',b1);
                    showHide('hide',b2);
                    showHide('hide',b3);
                    showHide('hide',b4);
                    showHide('hide',b5);

                    if( $(csa).prop('checked') ) 
                        showHide('show',s1);
                        showHide('hide',s2);
                        showHide('hide',s3);
                        showHide('hide',s4);
                        showHide('hide',s5);
                    
                
                else if( $(ismc).val() == localPickup )
                
                    showHide('hide',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('hide',b4);
                    showHide('hide',b5);

                    if( $(csa).prop('checked') ) 
                        showHide('hide',s1);
                        showHide('show',s2);
                        showHide('show',s3);
                        showHide('hide',s4);
                        showHide('hide',s5);
                    
                
                else
                
                    showHide('show',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('show',b4);
                    showHide('show',b5);

                    if( $(csa).prop('checked') ) 
                        showHide('show',s1);
                        showHide('show',s2);
                        showHide('show',s3);
                        showHide('show',s4);
                        showHide('show',s5);
                    
                
            );

            // When "shipping to different address" is changed (Live event)
            $(csa).click( function() 
                if( $(ismc).val() == pickPoint && $(this).prop('checked') )
                
                    showHide('show',b1);
                    showHide('hide',b2);
                    showHide('hide',b3);
                    showHide('hide',b4);
                    showHide('hide',b4);

                    showHide('show',s1);
                    showHide('hide',s2);
                    showHide('hide',s3);
                    showHide('hide',s4);
                    showHide('hide',s5);
                
                else if( $(ismc).val() == localPickup && $(this).prop('checked') )
                
                    showHide('hide',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('hide',b4);
                    showHide('hide',b4);

                    showHide('hide',s1);
                    showHide('show',s2);
                    showHide('show',s3);
                    showHide('hide',s4);
                    showHide('hide',s5);
                
                else
                
                    showHide('show',b1);
                    showHide('show',b2);
                    showHide('show',b3);
                    showHide('show',b4);
                    showHide('show',b4);

                    showHide('show',s1);
                    showHide('show',s2);
                    showHide('show',s3);
                    showHide('show',s4);
                    showHide('show',s5);
                
            );
        );
    </script>
    <?php


// Checkout conditional fields validation
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() 
    // HERE your shipping methods rate IDs
    $local_pickup = 'local_pickup:20';
    $pickpoint    = 'wc_custom_shipping_pickpoint';


    $chosen_shipping_method = WC()->session->get( 'chosen_shipping_methods' )[0];
    $billing                = '<strong> ' . __('Billing', 'woocommerce') . ' ';
    $shipping               = '<strong> ' . __('Shipping', 'woocommerce') . ' ';
    $country                = __('country.', 'woocommerce');
    $address1               = __('address.', 'woocommerce');
    $postcode               = __('postcode.', 'woocommerce');
    $state                  = __('state.', 'woocommerce');
    $end_text               = '</strong> '. __('is a required field.', 'woocommerce');

    if( $chosen_shipping_method == $local_pickup ) 
        if( empty($_POST['billing_address_1']) )
            wc_add_notice( $billing . $address1 . $end_text, 'error' );

        if( $_POST['ship_to_different_address'] )
            if( empty($_POST['shipping_address_1']) )
                wc_add_notice( $shipping . $address1 . $end_text, 'error' );
        
    
    elseif( $chosen_shipping_method == $pickpoint ) 
        if( empty($_POST['billing_country']) )
            wc_add_notice( $billing . $country . $end_text, 'error' );

        if( $_POST['ship_to_different_address'] )
            if( empty($_POST['shipping_country']) )
                wc_add_notice( $shipping . $country . $end_text, 'error' );
        
    
    else 
        if( empty($_POST['billing_country']) )
            wc_add_notice( $billing . $country . $end_text, 'error' );

        if( empty($_POST['billing_address_1']) )
            wc_add_notice( $billing . $address1 . $end_text, 'error' );

        if( empty($_POST['billing_postcode']) )
            wc_add_notice( $billing . $postcode . $end_text, 'error' );

        if( empty($_POST['billing_state']) )
            wc_add_notice( $billing . $state . $end_text, 'error' );

        if( $_POST['ship_to_different_address'] )
            if( empty($_POST['shipping_country']) )
                wc_add_notice( $shipping . $country . $end_text, 'error' );

            if( empty($_POST['shipping_address_1']) )
                wc_add_notice( $shipping . $address1 . $end_text, 'error' );

            if( empty($_POST['shipping_postcode']) )
                wc_add_notice( $shipping . $postcode . $end_text, 'error' );

            if( empty($_POST['shipping_state']) )
                wc_add_notice( $shipping . $state . $end_text, 'error' );
        
    

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

这是在 WooCommerce 3+ 上测试并运行的

【讨论】:

对我来说,地址、邮政编码等都是强制性的,即使在选择方法时它不可见。 @AbuNooh 在此答案中,这些字段需要由 jQuery 代码设置为必填项。在 Woocommerce 3.4 之前一切正常。现在 WC 3.4 已在 php.ini 中由参数 'required' =&gt; false 设置的非必需字段标签添加了“(可选)”。我找到了删除“(可选)”的方法,但是 Woocommerce jQuery 事件正在将它们添加回结帐页面。所以我还没有解决 WC 3.4.x 引入的这个特定问题的解决方案。 @AbuNooh 最后我找到了正确的方法……在你的问题中查看我更新的答案。 2021 年有没有更简单的方法来管理这个?所有这些代码只是为了取消设置基于运输的几个字段似乎有点矫枉过正?

以上是关于根据 Woocommerce 3 中的运输方式显示或隐藏结帐字段的主要内容,如果未能解决你的问题,请参考以下文章

根据 WooCommerce 结帐字段值显示/隐藏运输方式

根据 WooCommerce 中的运输类别自定义计算的运输成本

根据 Woocommerce 中的运输方式和付款方式添加费用

在 Woocommerce 中选择的运输方式更改时显示或隐藏 html 元素

根据运输方式更改 Woocommerce 订单状态

WooCommerce:根据运输方式自动完成已付款订单