简体   繁体   English

在 WooCommerce 购物车页面中添加费用的自定义复选框

[英]Custom checkbox that adds a fee in WooCommerce cart page

Based on Display a checkbox that add a fee in Woocommerce checkout page answer code I am trying to change usage to Cart page, rather than checkout page per clients request.基于在 Woocommerce 结帐页面答案代码中显示一个添加费用的复选框,我正在尝试将用法更改为购物车页面,而不是根据客户请求更改结帐页面。

So far I managed to display custom fee check box on cart page and trigger Ajax.到目前为止,我设法在购物车页面上显示自定义费用复选框并触发 Ajax。

However Cart totals are not updated.但是购物车总数不会更新。 If someone can help on code or point me in right direction?如果有人可以在代码上提供帮助或为我指明正确的方向?

// Display the custom checkbox field in cart

add_action( 'woocommerce_cart_totals_before_order_total', 'fee_installment_checkbox_field', 20 );
function fee_installment_checkbox_field(){
    echo '<tr class="packing-select"><th>Priority Dispatch</th><td>';

    woocommerce_form_field( 'priority_fee', array(
        'type'          => 'checkbox',
        'class'         => array('installment-fee form-row-wide'),
        'label'         => __(' $20.00'),
        'placeholder'   => __(''),
    ), WC()->session->get('priority_fee') ? '1' : '' );

    echo '<div class="tooltip">?
  <span class="tooltiptext">By selecting this option... </span>
</div></td>';
}

// jQuery - Ajax script
add_action( 'wp_footer', 'woo_add_cart_fee' );
function woo_add_cart_fee() {
    // Only on Checkout
    if(  ! is_wc_endpoint_url() ) :

    if( WC()->session->__isset('priority_fee') )
        WC()->session->__unset('priority_fee')
    ?>
    <script type="text/javascript">
    jQuery( function($){
        //if (typeof wc_add_to_cart_params  === 'undefined')
          //  return false;

        $('tr.packing-select').on('change', 'input[name=priority_fee]', function(){
            console.log('tests');
            var fee = $(this).prop('checked') === true ? '1' : '';
            
            

            $.ajax({
                type: 'POST',
                //url: wc_add_to_cart_params.ajax_url,
                data: {
                    'action': 'priority_fee',
                    'priority_fee': fee,
                },
                success: function (response) {
                    $('body').trigger('added_to_cart');
                },
            });
        });
    });
    </script>
    <?php
    endif;
    
}


// Get Ajax request and saving to WC session
add_action( 'wp_ajax_priority_fee', 'get_priority_fee' );
add_action( 'wp_ajax_nopriv_priority_fee', 'get_priority_fee' );
function get_priority_fee() {
    if ( isset($_POST['priority_fee']) ) {
        WC()->session->set('priority_fee', ($_POST['priority_fee'] ? true : false) );
    }
    die();
}


// Add a custom calculated fee conditionally
add_action( 'woocommerce_cart_calculate_fees', 'set_priority_fee' );
function set_priority_fee( $cart ){
    if ( is_admin() && ! defined('DOING_AJAX') )
        return;

    if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
        return;

    if ( 1 == WC()->session->get('priority_fee') ) {
        $items_count = WC()->cart->get_cart_contents_count();
        $fee_label   = sprintf( __( "PRIORITY DISPATCH %s %s" ), '&times;', $items_count );
        $fee_amount  = 20;
        WC()->cart->add_fee( $fee_label, $fee_amount );
    }
}

add_filter( 'woocommerce_form_field' , 'remove_optional_txt_from_installment_checkbox', 10, 4 );
function remove_optional_txt_from_installment_checkbox( $field, $key, $args, $value ) {
    // Only on checkout page for Order notes field
    if( 'priority_fee' === $key ) {
        $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}

Additionally is this the way this should be done, or is there an easier way to do it?此外,这是应该这样做的方式,还是有更简单的方法来做到这一点?

There are some mistakes in your code.您的代码中有一些错误。 Also, on cart page, jQuery events and Ajax behavior are a bit different, so it requires some changes:此外,在购物车页面上,jQuery 事件和 Ajax 行为有些不同,因此需要进行一些更改:

// Display the checkout field in cart page totals section
add_action( 'woocommerce_cart_totals_before_order_total', 'display_priority_fee_checkbox_field', 20 );
function display_priority_fee_checkbox_field(){
    echo '<tr class="installment-section">
    <th>'.__("Priority Dispatch").'</th><td>';

    woocommerce_form_field( 'priority_fee', array(
        'type'          => 'checkbox',
        'class'         => array('form-row-wide'),
        'label'         => __(' $20.00'),
    ), WC()->session->get('priority_fee') ? '1' : '' );

    echo '<div class="tooltip">?
    <span class="tooltiptext">'.__("By selecting this option... ").'</span>
    </div></td>';
}

// Remove "(optional)" text from the field
add_filter( 'woocommerce_form_field' , 'remove_optional_txt_from_priority_fee_checkbox', 10, 4 );
function remove_optional_txt_from_priority_fee_checkbox( $field, $key, $args, $value ) {
    // Only on checkout page for Order notes field
    if( 'priority_fee' === $key ) {
        $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}

// jQuery :: Ajax script
add_action( 'wp_footer', 'priority_fee_js_script' );
function priority_fee_js_script() {
    // On Order received page, remove the wc session variable if it exist
    if ( is_wc_endpoint_url('order-received')
        && WC()->session->__isset('priority_fee') ) :

        WC()->session->__unset('priority_fee');

    // On Cart page: jQuert script
    elseif ( is_cart() ) :

    ?>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof woocommerce_params === 'undefined')
            return false;

        var c = 'input[name=priority_fee]';

        $(document.body).on( 'click change', c, function(){
            console.log('click');
            var fee = $(c).is(':checked') ? '1' : '';

            $.ajax({
                type: 'POST',
                url: woocommerce_params.ajax_url,
                data: {
                    'action': 'priority_fee',
                    'priority_fee': fee,
                },
                success: function (response) {
                    setTimeout(function(){
                        $(document.body).trigger('added_to_cart');
                    }, 500);
                },
            });
        });
    });
    </script>
    <?php
    endif;
}

// Get Ajax request and saving to WC session
add_action( 'wp_ajax_priority_fee', 'priority_fee_ajax_receiver' );
add_action( 'wp_ajax_nopriv_priority_fee', 'priority_fee_ajax_receiver' );
function priority_fee_ajax_receiver() {
    if ( isset($_POST['priority_fee']) ) {
        $priority_fee = $_POST['priority_fee'] ? true : false;
        // Set to a WC Session variable
        WC()->session->set('priority_fee', $priority_fee );

        echo $priority_fee ? '1' : '0';
        die();
    }
}

// Add a custom calculated fee conditionally
add_action( 'woocommerce_cart_calculate_fees', 'set_priority_fee' );
function set_priority_fee( $cart ){
    if ( is_admin() && ! defined('DOING_AJAX') )
        return;

    if ( WC()->session->get('priority_fee') ) {
        $item_count  = $cart->get_cart_contents_count();
        $fee_label   = sprintf( __( "PRIORITY DISPATCH %s" ), '&times; ' . $item_count );
        $fee_amount  = 20 * $item_count;
        $cart->add_fee( $fee_label, $fee_amount );
    }
}

Code goes in functions.php file of your active child theme (or active theme).代码进入您的活动子主题(或活动主题)的 functions.php 文件。 Tested and works.测试和工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM