根据Woocommerce结帐中的单选按钮动态更新费用 [英] Update fee dynamically based on radio buttons in Woocommerce checkout

查看:83
本文介绍了根据Woocommerce结帐中的单选按钮动态更新费用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在为woocommerce开发一个插件,并且我添加了一个包装选择,既可以装在塑料袋中,也可以装在卡通盒中,每种包装的成本都不同.

So I'm developing a plugin for woocommerce, and I have added a selection for packing, either in a plastic bag or in Cartoon Box with each having a different cost.

用户选择一个选项,我需要WordPress刷新价格并通过使用以下方法添加正确的费用来更新成本:

Ones the user selects one of the options I need the WordPress to refresh the prices and update the cost by adding in the correct fee by using:

WC_Cart $cart->add_fee( 'Emballagegebyr', intval($fees));

增加WC_Cart费用并更新价格的最佳方法是什么?以及代码的外观如何?

What is the best way to have the WC_Cart fee added and update the price? and how should the code look like?

使用$ _GET和$ _POST来获取值还是可以的,甚至更好的方法是使用AJAX来更新价格而不刷新页面吗?

And is it okay to use $_GET and $_POST to get the values or even better is there a way to use AJAX to update the price without refreshing the page?

当前,我正在使用$ _GET通过以下代码从浏览器获取数据

Currently, I'm using $_GET to get the data from the browser by the following code

function at87_add_custom_fees( WC_Cart $cart ){
    $fees = 3; // fee amount
    $fees = isset($_GET['test']) ? $_GET['test'] : 3;

    $cart->add_fee( 'Emballagegebyr', intval($fees));
}

然后我的计划是可能添加如下所示的Javascript代码,然后使用单选按钮刷新页面并传递所选的选项.

and my plan is then to maybe add a Javascript code like below to then use the radio button to refresh the page and pass the selected option.

add_action( 'wp_footer', 'woocommerce_add_gift_box' );
function woocommerce_add_gift_box() {
    if (is_checkout()) {
    ?>
    <script type="text/javascript">
    jQuery( document ).ready(function( $ ) {
       // $('#add_gift_box').click(function(){
    //       jQuery('body').trigger('update_checkout');
    //    });

        $("#pakpose1 input:radio").change(function(){
    // Do something interesting here
            alert("test");
        });
    });
    </script>
    <?php
    }
}

我不确定这是否是最聪明的方法,或者是否还有另一种方法可能会更好,以及它可能会对安全产生什么影响,也许有些钩子可以做到工作完成.

I'm not sure though if this is the smartest way to do it, and or if there is another way, that could be better, and what security affect it might have, maybe there are some hooks that can get the same job done.

BTW:要在结帐页面中获得单选按钮,我以使其覆盖woocommerce review-order.php的方式制作了插件,并在该模板中添加了单选按钮,如下所示:

BTW: To get the radio buttons in the checkout-page I have made the plugin in such way that it override the woocommerce review-order.php and added the radio buttons in that template as following:

<tr class="packing-selections">
      <th>Pakning</th>
      <td>
                <input type="radio" id="pakpose1" name="pakpose" value="pakpose" checked="checked">Pak i pose <?php echo get_woocommerce_currency_symbol() ?>3.00<br>
                <input type="radio" id="pakpose2" name="pakpose" value="pakkasse">Pak i papkasse <?php echo get_woocommerce_currency_symbol() ?>9.00
     </td>
</tr>

推荐答案

代码已于2019年更新:也适用于非登录用户,并且适用于最新的WooCommerce版本3.7.x

Code updated on 2019: Works for non logged users too and on last WooCommerce version 3.7.x

这需要Ajax,没有它就无法完成……这是Ajax的方式.在这段代码中,您已经掌握了所有内容,因此请在尝试之前删除相关的自定义项(这意味着从模板和所有相关代码中删除单选按钮)…

This needs Ajax and can not be done without it… Here is the Ajax way. In this code you got everything, so remove your related customizations before trying it (meaning remove your radio buttons from template and all related code)…

完整代码(不需要其他内容):

// Customizing Woocommerce radio form field
add_action( 'woocommerce_form_field_radio', 'custom_form_field_radio', 20, 4 );
function custom_form_field_radio( $field, $key, $args, $value ) {
    if ( ! empty( $args['options'] ) && is_checkout() ) {
        $field = str_replace( '</label><input ', '</label><br><input ', $field );
        $field = str_replace( '<label ', '<label style="display:inline;margin-left:8px;" ', $field );
    }
    return $field;
}

// Add a custom dynamic packaging fee
add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1 );
function add_packaging_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee
    $fee = $packing_fee === 'box' ? 9.00 : 3.00;
    $cart->add_fee( __( 'Packaging fee', 'woocommerce' ), $fee );
}

// Add a custom radio fields for packaging selection
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_form_packing_addition', 20 );
function checkout_shipping_form_packing_addition() {
    $domain = 'woocommerce';

    echo '<tr class="packing-select"><th>' . __('Packing options', $domain) . '</th><td>';

    $chosen   = WC()->session->get('chosen_packing');
    $chosen   = empty($chosen) ? WC()->checkout->get_value('radio_packing') : $chosen;
    $chosen   = empty($chosen) ? 'bag' : $chosen;

    // Add a custom checkbox field
    woocommerce_form_field( 'radio_packing', array(
        'type' => 'radio',
        'class' => array( 'form-row-wide packing' ),
        'options' => array(
            'bag' => __('In a bag '.wc_price(3.00), $domain),
            'box' => __('In a gift box '.wc_price(9.00), $domain),
        ),
        'default' => $chosen,
    ), $chosen );

    echo '</td></tr>';
}

// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_shipping_packing_script' );
function checkout_shipping_packing_script() {
    if ( ! is_checkout() )
        return; // Only checkout page
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name=radio_packing]', function(e){
            e.preventDefault();
            var p = $(this).val();
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'woo_get_ajax_data',
                    'packing': p,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                    console.log('response: '+result); // just for testing | TO BE REMOVED
                },
                error: function(error){
                    console.log(error); // just for testing | TO BE REMOVED
                }
            });
        });
    });
    </script>
    <?php

}

// Php Ajax (Receiving request and saving to WC session)
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
function woo_get_ajax_data() {
    if ( isset($_POST['packing']) ){
        $packing = sanitize_key( $_POST['packing'] );
        WC()->session->set('chosen_packing', $packing );
        echo json_encode( $packing );
    }
    die(); // Alway at the end (to avoid server error 500)
}

代码进入您的活动子主题(或活动主题)的functions.php文件中. 经测试可正常工作.

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

类似:根据Woocommerce结帐中的选择字段添加动态费用

这篇关于根据Woocommerce结帐中的单选按钮动态更新费用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆