4

I am trying to add a fee to checkout based on whether or not a custom checkbox I've added it checked. I am really close to getting this to work, but I'm having issues getting the post values to determine if the fee should be applied or not.

Here is the code I have for my custom field:

add_action( 'woocommerce_after_checkout_billing_form', 'my_custom_fields' );
function my_custom_fields( $checkout ) {


  echo '<div id="message_fields"><h3>' . __('Add a Message') . '</h3>';
    woocommerce_form_field( 'add_gift_message', array(
        'type'          => 'checkbox',
        'class'         => array('gift_message form-row-wide'),

        'label'         => __('5x7 Enclosed Personal Message - $4'),
        'placeholder'   => __(''),
        ), $checkout->get_value( 'add_gift_message' ));

    woocommerce_form_field( 'gift_message', array(
        'type'          => 'textarea',
        'class'         => array('gift_message_text form-row-wide'),

        'label'         => false,
        'placeholder'   => __('Your message'),
        ), $checkout->get_value( 'gift_message' )); 
    echo '</div>';
}

This works, and the fields show up perfectly.

At the bottom of form-checkout.php in my theme, I have added this javascript to update the cart total when the field it checked:

<script type="text/javascript">
jQuery( document ).ready(function( $ ) {

$('#add_gift_message').click(function(){
    if ( $(this).is(':checked') ) { 
        $('#gift_message_field').show();
        var gift_message= true;
    } else { 
        $('#gift_message_field').hide();
        var gift_message = false;
    }
    $.ajax({
        type:       'POST',
        url:        wc_checkout_params.ajax_url,
        data:       $( 'form.checkout' ).serialize(),
        success:    function( response ) {
                if ( response ) {
                        var order_output = $(response);
                        $( '#order_review' ).html( $.trim( order_output ) );
                        $('body').trigger('update_checkout');
                    }
        },
        error: function(code){
        },
        dataType: 'html'
    });
});
});
</script>

This updates the order total and runs the following code (this is where the problem is):

add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );

function woo_add_cart_fee( $data ){
    global $woocommerce;

    if ( isset($_POST['add_gift_message']) )
        $woocommerce->cart->add_fee( 'Personal Gift Message', '4.00', true, 'standard' );

}

I know this part is being called because if I take out if ( isset($_POST['add_gift_message']) ), it adds the fee. What I'm having trouble with is determining if the field has been checked or not - I can't seem to get the POST values inside of woo_add_cart_fee no matter what I do.

Does anyone know how to get this to work? Thank you!!

  • Is woo_add_cart_fee a function that you created? If yes then could you possibly add additional argument that indicates if the checkbox is checked or not rather than checking for the POST array in the function itself ? It is possible that the scope is $_POST is lost by the time the control comes to the woo_add_cart_fee function. – Maximus2012 Mar 27 '15 at 20:10
  • It is a function I added, but what I ended up doing was creating a product that shows on the cart and on the checkout as something they can add to their order. It seems to be working out pretty well. – Tabytha Rourke Mar 31 '15 at 15:31

1 Answers1

0

The reason why you unable to get value from $_POST['add_gift_message'] is because update_checkout is an ajax event and it serialise form data into $_POST['post_data']. So, in order to cater for getting the value before (ajax) and during(non-ajax) user check out, you can get that by using below code:

if ( isset( $_POST['post_data'] ) ) {
    parse_str( $_POST['post_data'], $post_data );
} else {
    $post_data = $_POST; // fallback for final checkout (non-ajax)
}

if ( isset( $post_data['add_gift_message'] ) ) {

    $woocommerce->cart->add_fee( 'Personal Gift Message', '4.00', true, 'standard' );
}

for reference, can see this post

Community
  • 1
  • 1
titan
  • 524
  • 1
  • 6
  • 19