I am using Update fee dynamically based on radio buttons in Woocommerce checkout answer code solution that worked very well for me to add checkbox fields with a different price for each one, and the price changes are reflected in the checkout.
But I need some help: When I select a type of packaging with additional tax, it appears in the backend in the order area, but only shows the price, and I would like to show the title as well.
The checkbox options have:
'options' => array ( 'bag' => __ ('In a bag' .wc_price (3.00), $ domain), 'box' => __ ('In a gift box' .wc_price (9.00), $ domain), ),
How to make it show the name on the order? Also if it’s possible to change the checkboxes to select field instead?
Advertisement
Answer
I have made some changes to the original code that will:
- Display a custom select field (instead of radio buttons input fields)
- Display a custom error notice if customer has not selected a packing option
- Display the selected packing type everywhere (on orders and email notifications)
The code:
// Add a custom select fields for packing option fee 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'); // Add a custom checkbox field woocommerce_form_field( 'chosen_packing', array( 'type' => 'select', 'class' => array( 'form-row-wide packing' ), 'options' => array( '' => __("Choose a packing option ...", $domain), 'bag' => sprintf( __("In a bag (%s)", $domain), strip_tags( wc_price(3.00) ) ), 'box' => sprintf( __("In a gift box (%s)", $domain), strip_tags( wc_price(9.00) ) ), ), 'required' => true, ), $chosen ); echo '</td></tr>'; } // jQuery - Ajax script add_action( 'wp_footer', 'checkout_shipping_packing_script' ); function checkout_shipping_packing_script() { // Only checkout page if ( is_checkout() && ! is_wc_endpoint_url() ) : WC()->session->__unset('chosen_packing'); ?> <script type="text/javascript"> jQuery( function($){ $('form.checkout').on('change', 'select#chosen_packing', function(){ var p = $(this).val(); console.log(p); $.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 endif; } // 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) } // 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; $domain = "woocommerce"; $packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee if ( $packing_fee === 'bag' ) { $label = __("Bag packing fee", $domain); $cost = 3.00; } elseif ( $packing_fee === 'box' ) { $label = __("Gift box packing fee", $domain); $cost = 9.00; } if ( isset($cost) ) $cart->add_fee( $label, $cost ); } // Field validation, as this packing field is required add_action('woocommerce_checkout_process', 'packing_field_checkout_process'); function packing_field_checkout_process() { // Check if set, if its not set add an error. if ( isset($_POST['chosen_packing']) && empty($_POST['chosen_packing']) ) wc_add_notice( __( "Please choose a packing option...", "woocommerce" ), 'error' ); }
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
The error message when customer hasn’t chosen a packing option: