The following code displays a custom checkbox before add to cart button on single product pages:
add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 ); function output_custom_text_field() { //Lots of code then: <input type="checkbox" id="option1" name="option1"> }
Now I would like to trap/capture this checkbox option in Woocommerce session and then make a custom price calculations in the following code:
function final_cart_update( $cart_object ) { foreach ( $cart_object->get_cart() as $cart_item ) { // get the custom pricing for this product if (isset( $_POST['option1'])) { $pricing_custom = get_post_meta( $cart_item['product_id'], '_number_field_1', true ); } // get product price $price = floatval( $cart_item['data']->get_price() ); // set new price $cart_item['data']->set_price( $price + $pricing_custom ); } } add_action( 'woocommerce_before_calculate_totals', 'final_cart_update', 99, 1 );
What is missing is the part that will capture the checkbox option to set it in sessions, like:
if (isset( $_POST['option1'])) { // Set it in session }
Any help is appreciated.
Admin Part of the code →
/*-------------------------------------------*/ /* 5. Adding Custom Field */ /*-------------------------------------------*/ // Add custom fields in "product data" settings metabox ("Advanced" tab) add_action('woocommerce_product_options_advanced','woocious_add_custom_field_product_dashboard'); function woocious_add_custom_field_product_dashboard(){ global $post; echo '<div class="product_custom_field">'; // Checkbox Field woocommerce_wp_checkbox( array( 'id' => 'woocious_custom_services_fields', 'description' => __('Select if you want add on services', 'woocious'), 'label' => __('Display custom add on services', 'woocious'), 'desc_tip' => 'true', ) ); // Minimum Letter Text Box woocommerce_wp_text_input( array( 'id' => 'addon_service_1', 'label' => __('Service 1', 'woocommerce'), 'description' => __('set custom minimum Lettering text field', 'woocommerce'), 'desc_tip' => 'true', ) ); // Number Field woocommerce_wp_text_input( array( 'id' => '_number_field_1', 'label' => __( 'Service amount 1', 'woocommerce' ), 'placeholder' => '', 'desc_tip' => false, 'description' => __( "Please enter the service amount", 'woocommerce' ), 'type' => 'number', 'desc_tip' => 'true', 'custom_attributes' => array( 'step' => 'any', 'min' => '0' ) ) ); // Maximum Letter Text Box woocommerce_wp_text_input( array( 'id' => 'addon_service_2', 'label' => __('Service 2', 'woocommerce'), 'description' => __('set custom maximum Lettering text field', 'woocommerce'), 'desc_tip' => 'true' ) ); // Number Field woocommerce_wp_text_input( array( 'id' => '_number_field_2', 'label' => __( 'Service amount 2', 'woocommerce' ), 'placeholder' => '', 'desc_tip' => false, 'description' => __( "Please enter the service amount", 'woocommerce' ), 'type' => 'number', 'desc_tip' => 'true', 'custom_attributes' => array( 'step' => 'any', 'min' => '0' ) ) ); echo '</div>'; } // Save Inputted Entries, in the Product Dashboard Text Fields. add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save'); function woocommerce_product_custom_fields_save($post_id){ // Checkbox Field $checkbox = isset( $_POST['woocious_custom_services_fields'] ) ? 'yes' : 'no'; update_post_meta( $post_id, 'woocious_custom_services_fields', $checkbox ); // Save Minimum Letters if ( isset( $_POST['addon_service_1'] ) ) update_post_meta($post_id, 'addon_service_1', sanitize_text_field( $_POST['addon_service_1'] ) ); // Save Maximum Letters if ( isset( $_POST['addon_service_2'] ) ) update_post_meta($post_id, 'addon_service_2', sanitize_text_field( $_POST['addon_service_2'] ) ); // Save the services amount if ( isset( $_POST['_number_field_1'] ) ) update_post_meta($post_id, '_number_field_1', sanitize_text_field( $_POST['_number_field_1'] ) ); }
Outputting HTML on Product Page →
// Output Custom Text Field to Product Page add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 ); function output_custom_text_field() { // Get the checkbox value $custom_option = get_post_meta( $post->ID, 'woocious_custom_services_fields', true ); // If is single product page and have the "custom text option" enabled we display the field if ( is_product() && ! empty($custom_option) ) { ?> <div class="woociousbuy_inner"> <div class="woociousbuy_two"> <h3>Add on Services</h3> <input type="checkbox" id="option1" name="option1"> <label for="option1"><?php global $post; echo get_post_meta($post->ID,'addon_service_1',true);?> <svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg> </label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_1',true);?></span> </div> <div class="woociousbuy_inner"> <input type="checkbox" id="option2" name="option2"/> <label for="option2"><?php global $post; echo get_post_meta($post->ID,'addon_service_2',true);?> <svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg> </label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_2',true);?></span> </div> </div> <?php } }
Advertisement
Answer
You don’t need to use any session for that. Use woocommerce_add_cart_item_data
filter hook like:
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_option_checkbox_field' ); function custom_product_option_checkbox_field() { echo '<p><label><input type="checkbox" id="option1" name="option1"> '.__("Option 1").'</label></p>'; } // Add selected add-on option as custom cart item data add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 ); function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id ) { if ( isset( $_POST['option1'] ) && $pricing_custom = get_post_meta( $product_id, '_number_field_1', true ) ) { $cart_item_data['pricing_custom'] = $pricing_custom; $cart_item_data['unique_key'] = md5( microtime().rand() ); // Make each item unique } return $cart_item_data; } // Change the product price add_action( 'woocommerce_before_calculate_totals', 'action_before_calculate_totals_callback', 10, 1 ); function action_before_calculate_totals_callback( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // Avoiding hook repetition and price calculation problems if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; // Loop through cart items foreach ( $cart->get_cart() as $cart_item ) { if ( isset( $cart_item['pricing_custom'] ) ) { // Set the calculated price $cart_item['data']->set_price( $cart_item['data']->get_price() + $cart_item['pricing_custom'] ); } } }
Code goes in functions.php file of your active child theme (or active theme). Tested and works.