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

Posted

技术标签:

【中文标题】根据 WooCommerce 结帐字段值显示/隐藏运输方式【英文标题】:Show/hide shipping methods based on a WooCommerce checkout field value 【发布时间】:2019-09-14 03:32:40 【问题描述】:

在 WooCommerce 中,我设置了不同的运输方式但其中一种必须是公司独有的。

为此,我使用以下代码:

add_filter( 'woocommerce_package_rates', array( $this, 'package_rates' ), 10, 2 );

public function package_rates( $rates, $package ) 
    $company_rate_id = 'flat_rate:7';

    if(!empty(WC()->customer->get_billing_company()))
        $company_rates = $rates[ $company_rate_id ];
        $rates = array( $company_rate_id => $company_rates );
    else
        unset( $rates[ $company_rate_id ] );
    

    return $rates;

该解决方案有效,但前提是计费公司已经存在并保存在数据库中。因此,如果客户在结帐页面上更新此信息,它就不起作用了。

可能的解决方案是实时保存该字段(billing_company)。

我尝试了以下功能:

add_filter( 'woocommerce_checkout_fields' , 'trigger_update_checkout_on_change' );
function trigger_update_checkout_on_change( $fields ) 

    $fields['billing']['billing_company']['class'][] = 'update_totals_on_change';

    return $fields;

这更新了运输方式,问题又是,该字段没有保存在数据库中,package_rates()函数无法实时找到它。

【问题讨论】:

【参考方案1】:

这比那要复杂一些……需要 jQuery 和 Ajax 代码才能根据结帐字段用户输入显示/隐藏运输方式。

以下代码将启用根据结帐公司字段显示/隐藏预定义的运输方式:

// Conditionally show/hide shipping methods
add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) 
    // The defined rate id
    $company_rate_id = 'flat_rate:7';

    if( WC()->session->get('company' ) === '1' ) 
        $rates = array( $company_rate_id => $rates[ $company_rate_id ] );
     else 
        unset( $rates[ $company_rate_id ] );
    
    return $rates;


// function that gets the Ajax data
add_action( 'wp_ajax_get_customer_company', 'wc_get_customer_company' );
add_action( 'wp_ajax_nopriv_get_customer_company', 'wc_get_customer_company' );
function wc_get_customer_company() 
    if ( isset($_POST['company']) && ! empty($_POST['company']) )
        WC()->session->set('company', '1' );
     else 
        WC()->session->set('company', '0' );
    
    die(); // (required)


// The Jquery Ajax script
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() 
    if( WC()->session->__isset('company') ) 
        WC()->session->__unset('company');

    // Only on checkout when billing company is not defined
    if( is_checkout() && ! is_wc_endpoint_url() ):
    ?>
    <script type="text/javascript">
    jQuery( function($)
        if (typeof wc_checkout_params === 'undefined') 
            return false;

        var fieldId = 'input#billing_company';

        function companyTriggerAjax( company )
            $.ajax(
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: 
                    'action': 'get_customer_company',
                    'company': company,
                ,
                success: function (result) 
                    // Trigger refresh checkout
                    $('body').trigger('update_checkout');
                
            );
        

        // On start
        if( $(fieldId).val() != '' ) 
            companyTriggerAjax( $(fieldId).val() );
        

        // On change
        $(fieldId).change( function () 
            companyTriggerAjax( $(this).val() );
        );
    );
    </script>
    <?php
    endif;


// Enabling, disabling and refreshing session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data )
    $bool = true;

    if ( WC()->session->get('company' ) === '1' )
        $bool = false;

    // Mandatory to make it work with shipping methods
    foreach ( WC()->cart->get_shipping_packages() as $package_key => $package )
        WC()->session->set( 'shipping_for_package_' . $package_key, $bool );
    
    WC()->cart->calculate_shipping();

代码进入您的活动子主题(或活动主题)的 function.php 文件中。经过测试并且可以工作。


相关:Remove shipping cost if custom checkbox is checked in WooCommerce Checkout

【讨论】:

有一个小问题,假设您已经在 billing 字段中存储了信息。如果您到达结帐处,删除该字段的内容并刷新页面(或导航到另一个部分),返回结帐时,帐单字段将显示已保存的内容,并且货件将显示为没有公司。反之亦然,如果没有保存公司,填写公司,导航返回,就会出现公司的发货。谢谢你的一切 @RafaelCalero 我已经更新了答案......它将处理您描述的情况,如果重新加载结帐页面,则从会话中删除数据。如果这个答案回答了你的问题,你可以请accept回答,谢谢。 提前,再次感谢。这解决了它最初为空的情况。但公司最初挽救的案例仍然失败。 你是对的!我一直在全新安装中进行测试,您的解决方案可以正常工作。它必须与之前的一些发展相冲突。谢谢你的一切

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

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

根据所选付款方式显示隐藏自定义 Woocommerce 结帐字段

根据取货和交付按钮显示或隐藏 WooCommerce 结帐字段

在 Woocommerce 中显示或隐藏两个结帐字段

根据选择的运输有条件地隐藏 WooCommerce 中的结帐字段

Wordpress - 单选按钮结帐 woocommerce 显示/隐藏必填字段