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

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

问题描述

所以我正在为 woocommerce 开发一个插件,并且我添加了一个包装选择,无论是在塑料袋中还是在卡通盒中,每个都有不同的成本.

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

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

添加 WC_Cart 费用和更新价格的最佳方法是什么?以及代码应该是什么样子的?

是否可以使用 $_GET 和 $_POST 来获取值,或者更好的是有没有一种方法可以使用 AJAX 更新价格而不刷新页面?

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

function at87_add_custom_fees( WC_Cart $cart ){$费用 = 3;//收费多少$fees = isset($_GET['test']) ?$_GET['test'] : 3;$cart->add_fee('Emballagegebyr', intval($fees));}

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

add_action('wp_footer', 'woocommerce_add_gift_box');函数 woocommerce_add_gift_box() {如果(is_checkout()){?><script type="text/javascript">jQuery( 文档 ).ready(function( $ ) {//$('#add_gift_box').click(function(){//jQuery('body').trigger('update_checkout');//});$("#pakpose1 input:radio").change(function(){//在这里做一些有趣的事情警报(测试");});});<?php}}

我不确定这是否是最聪明的方法,或者如果有另一种方法,那可能会更好,以及它可能对安全性产生什么影响,也许有一些钩子可以获得相同的效果工作完成.

顺便说一句:为了在结帐页面中获取单选按钮,我制作了插件以覆盖 woocommerce review-order.php 并在该模板中添加单选按钮,如下所示:

<th>包装</th><td><input type="radio" id="pakpose1" name="pakpose" value="pakpose" checked="checked">Pak ipose <?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

这需要 Ajax,没有它就无法完成……这是 Ajax 方式.在这段代码中你得到了一切,所以在尝试之前删除你的相关自定义(意味着从模板和所有相关代码中删除你的单选按钮)......

完整代码(不需要别的):

//自定义 Woocommerce 单选表单字段add_action('woocommerce_form_field_radio', 'custom_form_field_radio', 20, 4);函数 custom_form_field_radio( $field, $key, $args, $value ) {if ( !empty( $args['options'] ) && is_checkout() ) {$field = str_replace( '
session->get('chosen_packing');//动态打包费$fee = $packing_fee === '盒子' ?9.00:3.00;$cart->add_fee( __( 'Packaging fee', 'woocommerce' ), $fee );}//为打包选择添加自定义单选字段add_action('woocommerce_review_order_after_shipping', 'checkout_shipping_form_packing_addition', 20);函数 checkout_shipping_form_packing_addition() {$domain = 'woocommerce';echo '<tr class="packing-select"><th>'.__('包装选项', $domain) .'</th><td>';$chosen = WC()->session->get('chosen_packing');$chosen = empty($chosen) ?WC()->checkout->get_value('radio_packing') : $chosen;$chosen = empty($chosen) ?'包' : $chosen;//添加自定义复选框字段woocommerce_form_field('radio_packing', array('类型' =>'收音机','类' =>数组('表格行宽包装'),'选项' =>大批('袋' =>__('在一个包里 '.wc_price(3.00), $domain),'盒子' =>__('在礼品盒中 '.wc_price(9.00), $domain),),'默认' =>$选择,), $选择 );回声'</td></tr>';}//jQuery - Ajax 脚本add_action('wp_footer', 'checkout_shipping_packing_script');函数 checkout_shipping_packing_script() {如果(!is_checkout())返回;//仅结帐页面?><script type="text/javascript">jQuery(函数($){$('form.checkout').on('change', 'input[name=radio_packing]', function(e){e.preventDefault();var p = $(this).val();$.ajax({类型:'POST',网址:wc_checkout_params.ajax_url,数据: {'动作':'woo_get_ajax_data','包装':p,},成功:功能(结果){$('body').trigger('update_checkout');console.log('响应:'+结果);//仅用于测试 |即将被删除},错误:函数(错误){控制台日志(错误);//仅用于测试 |即将被删除}});});});<?php}//Php Ajax(接收请求并保存到WC会话)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');函数 woo_get_ajax_data() {如果 ( isset($_POST['packing']) ){$packing = sanitize_key( $_POST['packing'] );WC()->session->set('chosen_packing', $packing );回声 json_encode( $packing );}死();//总是在最后(避免服务器错误 500)}

代码位于活动子主题(或活动主题)的 functions.php 文件中.经过测试并有效.

<块引用>

类似:

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.

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));

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

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?

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));
}

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: 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>

解决方案

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

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)…

The complete code (nothing else needed):

// 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)
}

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

Similar: Add a dynamic fee based on a select field in Woocommerce checkout

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

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