根据WooCommerce中的自定义结帐单选按钮和文本字段设置动态费用 [英] Set a dynamic fee based on custom checkout radio buttons and text field in WooCommerce
问题描述
我正在尝试创建一个自定义结帐单选按钮,以百分比计算餐厅的小费.
I am trying to create a custom checkout radio button that calculates restaurant tip in percentage.
对于单选按钮,静态值可以正常工作.
For the radio button, the static value is working fine.
但是,我想获取小计并在自定义单选按钮单击上计算一定百分比.
However, I want to get the subtotal and calculate certain percentage on custom radio button click.
这是我的代码
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( $checkout ) {
$chosen = WC()->session->get( 'tip' );
$chosen = empty( $chosen ) ? WC()->checkout->get_value( 'tip' ) : $chosen;
$chosen = empty( $chosen ) ? '0' : $chosen;
$total = WC()->cart->get_subtotal();
$fivetip = $total * 0.05;
woocommerce_form_field( 'tip', array(
'type' => 'radio',
'class' => array( 'form-row-wide', 'update_totals_on_change' ),
'options' => array(
$fivetip => '5%',
'10.00' => '10%',
'15.00' => '15%',
),
), $chosen );
woocommerce_form_field( 'add_tip', array(
'type' => 'text',
'class' => array('add_tipform-row-wide'),
'placeholder' => __('Enter Custom Tip Amount')
), $checkout->get_value( 'add_tip' ));
}
add_action( 'woocommerce_cart_calculate_fees', 'checkout_tip_fee', 20, 1 );
function checkout_tip_fee( $cart ) {
if ( $radio = WC()->session->get( 'tip' ) ) {
$cart->add_fee( 'Tip', $radio );
}
}
add_action( 'woocommerce_checkout_update_order_review', 'checkout_tip_choice_to_session' );
function checkout_tip_choice_to_session( $posted_data ) {
parse_str( $posted_data, $output );
if ( isset( $output['tip'] ) ){
WC()->session->set( 'tip', $output['tip'] );
}
}
推荐答案
以下是使用 Ajax和WC会话进行的高级操作:
The following is something advanced using Ajax and WC Sessions:
它将根据选定的单选按钮选项添加自定义提示(作为自定义费用):固定百分比选项或自定义选项,将显示文本字段以允许客户输入固定金额.
It will add a custom a tip (as a custom fee) based on selected radio buttons options: fixed percentages options or custom option that will show a text field to allow customer to input a fixed amount.
与WooCommerce表单字段的单选按钮相比,显示的字段经过手工编码,以获得更好的显示(请参见下面的屏幕截图).
Displayed Fields are hand coded to get a better display than WooCommerce form fields for radio buttons (see the screenshots below).
它如何为客户服务:
在结帐页面加载时,应用(默认选择) 5%的提示(收费).将所选选项更改为其他选项时,所应用的费用也会更改.
On checkout page load, a Tip of 5% (a fee) is applied (selected by default). When changing the selected option to something else, the applied fee changes.
如果自定义"选择了该选项,则在下面的文本字段出现时就删除了费用:
If the "custom" option is selected, the fee is removed while a text field appears below:
客户可以输入固定金额,并为此提示应用(费用).
Customer can input a fixed amount and a Tip (a fee) is applied with this amount.
以下是代码:
// Display custom checkout fields
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( ) {
// Here set your radio button options (Values / Labels pairs)
$options = array( '5' => '5%', '10' => '10%', '15' => '15%', 'custom' => __('Custom', 'woocommerce') );
// Radio button fields
echo '<style> #add_tip_field.form-row label { display:inline-block; margin-left:6px; } </style>
<p class="form-row form-row-wide" id="add_tip_field"><span class="woocommerce-input-wrapper">
<label for="add_tip"><strong>'.__('Add a tip', 'woocommerce'). ':</strong> </label>';
foreach ( $options as $value => $label_name ) {
$checked = $value == '5' ? ' checked="checked"' : '';
echo '<label for="add_tip_'.$value.'" class="radio ">
<input type="radio" class="input-radio " value="'.$value.'" name="add_tip" id="add_tip_'.$value.'"'.$checked.'> '.$label_name.'
</label>';
}
echo '</span></p>';
// Text field (hidden by default)
echo '<p class="form-row form-row-wide" id="custom_tip_field" style="display:none""><span class="woocommerce-input-wrapper">
<input type="text" class="input-text " name="custom_tip" id="custom_tip" value="" placeholder="'.__('Input a tip amount', 'woocommerce').'">
</span></p>';
}
// jQuery / Ajax script
add_action( 'woocommerce_after_checkout_form', 'wc_checkout_fee_script' );
function wc_checkout_fee_script() {
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
var addTip = 'input[name="add_tip"]',
customTip = 'input[name="custom_tip"]'
function triggerAjaxEvent( amount, type = 'percent' ){
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'tip_fee',
'amount': amount,
'type' : type
},
success: function (result) {
$(document.body).trigger('update_checkout');
console.log(result);
},
});
}
triggerAjaxEvent( $(addTip+':checked').val() );
$('form.checkout').on('change', addTip, function() {
var textField = $('#custom_tip_field'),
percent = $(this).val();
if( percent === 'custom' && textField.css('display') === 'none' ) {
textField.show(200);
} else if ( percent !== 'custom' && textField.css('display') !== 'none' ) {
textField.hide(200, function(){
$(customTip).val('');
});
}
triggerAjaxEvent( percent );
});
$('form.checkout').on('input change', customTip, function() {
triggerAjaxEvent( $(this).val(), 'custom' );
});
});
</script>
<?php
}
// Get Ajax request and save data to WC session
add_action( 'wp_ajax_tip_fee', 'get_tip_fee' );
add_action( 'wp_ajax_nopriv_tip_fee', 'get_tip_fee' );
function get_tip_fee() {
if ( isset($_POST['amount']) && isset($_POST['type']) ) {
$fee = is_numeric($_POST['amount']) && $_POST['amount'] > 0 ? floatval($_POST['amount']) : 0;
WC()->session->set('fee_data', array(
'type' => esc_attr($_POST['type']),
'amount' => $fee
) );
print_r(WC()->session->get('fee_data'));
}
die();
}
// Add a dynamic fee from WC Session ajax data
add_action( 'woocommerce_cart_calculate_fees', 'checkout_custom_tip_fee' );
function checkout_custom_tip_fee( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
return;
$data = WC()->session->get('fee_data');
$fee = $total = 0;
if ( isset($data['type']) && isset($data['amount']) ) {
// 1. Fixed Fee amount
if ( $data['type'] === 'custom' ) {
$text = $data['type'];
$fee = $data['amount'];
}
// 2. Calculated percentage Fee amount
elseif ( $data['type'] === 'percent' && $data['amount'] > 0 ) {
$text = $data['amount'] . '%';
// Get cart subtotal excl. Taxes (discounted)
foreach ( $cart->get_cart() as $cart_item ) {
$total = $cart_item['line_total'];
}
// Calculate fee
$fee = $total * $data['amount'] / 100 ;
}
// Add the fee
if ( $fee > 0 ) {
$cart->add_fee( sprintf( __('Tip (%s)', 'woocommerce' ), $text ), $fee );
}
}
}
代码进入活动子主题(或活动主题)的functions.php文件中.经过测试,可以正常工作.
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
与您的评论相关的添加:
要使用总计含
税的购物车项目在最后一个功能中替换:
To use cart items total including
taxes replace in last function:
// Get cart subtotal excl. Taxes (discounted)
foreach ( $cart->get_cart() as $cart_item ) {
$total = $cart_item['line_total'];
}
使用
// Get cart subtotal Incl. Taxes (discounted)
foreach ( $cart->get_cart() as $cart_item ) {
$total = $cart_item['line_total'] + $cart_item['line_tax'];
}
这篇关于根据WooCommerce中的自定义结帐单选按钮和文本字段设置动态费用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!