简体   繁体   中英

How to add a radio button with price on product page? WordPress woocommerce

How can to customize the product page to include an extract fee base on the user's choice. Something slimier to the attached photo with customize your order option on the product page not on checkout page. 在此处输入图片说明

I have this code which display the radio buttons and option on the checkout but for some reason the fee is not being added to the total.

    // Part 1
// Display Radio Buttons
// Uses woocommerce_form_field()

add_action( 'woocommerce_before_add_to_cart_form', 'bbloomer_checkout_radio_choice' );

function bbloomer_checkout_radio_choice() {

   $chosen = WC()->session->get('radio_chosen');
   $chosen = empty( $chosen ) ? WC()->checkout->get_value('radio_choice') : $chosen;
   $chosen = empty( $chosen ) ? 'no_option' : $chosen;

   $args = array(
   'type' => 'radio',
   'class' => array( 'form-row-wide' ),
   'options' => array(
      'no_option' => 'No Option',
      'option_1' => 'Option 1 ($10)',
      'option_2' => 'Option 2 ($30)',
   ),
   'default' => $chosen
   );

   echo '<div id="checkout-radio">';
   echo '<h3>Customize Your Order!</h3>';
   woocommerce_form_field( 'radio_choice', $args, $chosen );
   echo '</div>';

}

// Part 2
// Add Fee and Calculate Total
// Based on session's "radio_chosen"

#2 Calculate New Total

add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_checkout_radio_choice_fee', 20, 1 );

function bbloomer_checkout_radio_choice_fee( $cart ) {

  if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

  $radio = WC()->session->get( 'radio_chosen' );

  if ( "option_1" == $radio ) {
   $fee = 10;
  } elseif ( "option_2" == $radio ) {
   $fee = 30;
  }

  $cart->add_fee( __('Option Fee', 'woocommerce'), $fee );

}

// Part 3
// Refresh Checkout if Radio Changes
// Uses jQuery

add_action( 'wp_footer', 'bbloomer_checkout_radio_choice_refresh' );

function bbloomer_checkout_radio_choice_refresh() {
if ( ! is_checkout() ) return;
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name=radio_choice]', function(e){
            e.preventDefault();
            var p = $(this).val();
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'woo_get_ajax_data',
                    'radio': p,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                }
            });
        });
    });
    </script>
    <?php
}

// Part 4
// Add Radio Choice to Session
// Uses Ajax

add_action( 'wp_ajax_woo_get_ajax_data', 'bbloomer_checkout_radio_choice_set_session' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'bbloomer_checkout_radio_choice_set_session' );

function bbloomer_checkout_radio_choice_set_session() {
    if ( isset($_POST['radio']) ){
        $radio = sanitize_key( $_POST['radio'] );
        WC()->session->set('radio_chosen', $radio );
        echo json_encode( $radio );
    }
    die();
}

If I change the hook to add_action( 'woocommerce_product_options_general_product_data', 'bbloomer_checkout_radio_choice' );

The option buttons shows up on the check out page and it work fine, I assume some how I need to pass the option value from product page to the check out page

Add to follows code snippets to achieve your work -

function add_custom_fees_before_add_to_cart() {
    global $product;

    $args = array(
        'type' => 'radio',
        'class' => array( 'form-row-wide' ),
        'options' => array(
            '' => 'No Option',
            '10' => 'Option 1 ($10)',
            '30' => 'Option 2 ($30)',
        ),
        'default' => ''
    );
    ?>
    <div class="custom-fees-wrap">
        <label for="iconic-engraving"><?php _e( 'Customize Your Order!', 'textdomain' ); ?></label>
        <?php woocommerce_form_field( 'custom_fees', $args, '' ); ?>
    </div>
    <?php
}

add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_fees_before_add_to_cart', 99 );


function save_value_add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
    $custom_fees = filter_input( INPUT_POST, 'custom_fees' );

    if ( empty( $custom_fees ) ) {
        return $cart_item_data;
    }

    $cart_item_data['custom_fees'] = $custom_fees;

    return $cart_item_data;
}

add_filter( 'woocommerce_add_cart_item_data', 'save_value_add_cart_item_data', 99, 3 );

function calculate_add_cart_fee() {
    global $woocommerce;
    $cart_items = $woocommerce->cart->get_cart();
    foreach( $cart_items as $key => $item ) { 
        if( !isset( $item['custom_fees'] ) && empty( $item['custom_fees'] ) ) continue;
        $woocommerce->cart->add_fee( __('Custom fees', 'textdomain'), $item['custom_fees'] );
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'calculate_add_cart_fee', 99 );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM