我在我的网站上添加了一些自定义字段,这些字段显示在结帐中。这是关于夏令营的儿童注册。
它们是选择字段:
function person_details( $checkout ) {
global $woocommerce;
$count = $woocommerce->cart->cart_contents_count;
$i = 0;
for( $k=1; $k<= $count; $k++ ) {
$i++;
print ('<h3>Gegevens van kind #'.$i.'</h3>');
woocommerce_form_field( 'cstm_care'.$i, array(
'type' => 'select',
'required' => true,
'class' => array( 'my-field-class form-row-last' ),
'label' => __( 'Voor- en na zorg' ),
'options' => array(
'Geen' => __( 'Geen', 'njengah' ),
'Voorzorg' => __( 'Pre-care (€30)', 'njengah' ),
'Nazorg' => __( 'Aftercare (€30)', 'njengah' ),
'Voor- en na zorg' => __( 'Pre- & Aftercare (€50)', 'njengah' )
)), $checkout->get_value( 'cstm_care'.$i ));
}
}
我想根据所选选项更改结账时的总数:
我怎样才能实现这个目标?还可能吗?
它需要使用 WooCommerce 会话、JavaScript 和 Ajax,根据所选选项设置计算费用。
尝试以下操作:
// Utility function
function get_care_data( $type ) {
if ( $type === 'options' ) {
// Return options for the select fields
return array(
'geen' => __( 'Geen', 'woocommerce' ),
'voorzorg' => __( 'Voorzorg (€30)', 'woocommerce' ),
'nazorg' => __( 'Nazorg (€30)', 'woocommerce' ),
'beide' => __( 'Voor- en nazorg (€50)', 'woocommerce' ),
);
} else {
// Return pricing by option
return array(
'geen' => 0,
'voorzorg' => 30,
'nazorg' => 30,
'beide' => 50,
);
}
}
// Display fields
add_action( 'woocommerce_after_order_notes', 'display_custom_select_fields' );
function display_custom_select_fields( $checkout ) {
$count = WC()->cart->get_cart_contents_count();
for( $i = 1; $i <= $count; $i++ ) {
echo '<h3>' . esc_html__('Gegevens van kind', 'woocommerce') . ' #' . $i . '</h3>';
woocommerce_form_field( 'cstm_care'.$i, array(
'type' => 'select',
'class' => array('form-row-wide'),
'label' => esc_html__('Voor- en nazorg', 'woocommerce'),
'required' => true,
'options' => get_care_data('options'),
) );
}
}
// Javascript / Ajax
add_action( 'woocommerce_checkout_init', 'checkout_care_js' );
function checkout_care_js() {
$count = WC()->cart->get_cart_contents_count();
wc_enqueue_js("if (typeof wc_checkout_params === 'undefined') {
return false;
}
function processCare( index, selectedValue ) {
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'get_selected_care',
'field_index': index,
'selected_care': selectedValue
},
success: function (response) {
$(document.body).trigger('update_checkout');
}
});
}
for( let i = 1; i <= {$count}; i++ ) {
$('#cstm_care'+i).on('change', function() {
processCare( i, $(this).val() );
});
}");
}
// Get Ajax request and saving selected values to a WC Session variable
add_action( 'wp_ajax_get_selected_care', 'set_selected_care_to_wc_session' );
add_action( 'wp_ajax_nopriv_get_selected_care', 'set_selected_care_to_wc_session' );
function set_selected_care_to_wc_session() {
if ( isset($_POST['field_index']) && isset($_POST['selected_care']) ) {
$care_data = (array) WC()->session->get('care_data');
$care_data[intval($_POST['field_index'])] = esc_attr($_POST['selected_care']);
WC()->session->set('care_data', $care_data);
}
wp_die();
}
// Add a calculated fee based on selected options
add_action( 'woocommerce_cart_calculate_fees','add_cumulated_care_fees', 10 );
function add_cumulated_care_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
if ( is_checkout() && !is_wc_endpoint_url() ) {
$care_data = (array) WC()->session->get('care_data');
$care_costs = get_care_data('costs');
$fees_total = 0;
// Loop through selected care data
foreach ( $care_data as $selected_care ) {
$fees_total += $care_costs[$selected_care]; // Sum the cost of each selected care option
}
if( $fees_total > 0 ) {
$cart->add_fee( esc_html__('Care fees'), $fees_total, false ); // Add the calculated fee
}
}
}
// Save the selected care data in a multi-dimensional array (optional)
add_action('woocommerce_checkout_create_order', 'save_custom_select_fields_values', 22, 2 );
function save_custom_select_fields_values( $order, $data ) {
$items_count = WC()->cart->get_cart_contents_count();
$selected_care_data = array('count' => $items_count);
// Loop through care fields
for( $i = 1; $i <= $items_count; $i++ ) {
if ( isset($_POST['cstm_care'.$i]) ) {
$selected_care_data['fields'][$i] = esc_attr($_POST['cstm_care'.$i]); // Add each selected option
}
}
$order->update_meta_data( '_care_options', $selected_care_data ); // save data
}
代码位于子主题的functions.php 文件中(或插件中)。已测试并有效。