I have created a custom checkout field related to packaging and with different price options. It works nicely if I complete my order, all options are saved and appearing on thank you page/order email/admin edit order.
But, the issue is that if I select an option from this custom field and then continue browsing to another page, if I then go to checkout page again, the previously selected option is not displayed, somehow forgotten.
Can someone help me with adjustments to my code so that the options are saved and not forgotten?
Code is this (taken from this topic Add a dynamic fee based on a select field in WooCommerce Checkout and adjusted to suit my needs):
//Add a custom select fields for packing option fee
add_action( 'woocommerce_checkout_before_order_review', 'checkout_shipping_form_packing_addition', 40 );
function checkout_shipping_form_packing_addition( ) {
$domain = 'woocommerce';
echo '<tr class="packing-select"><th><h3>' . __('Packaging', $domain) . '</h3></th><td>';
$chosen = WC()->session->get('chosen_packing');
// Add a custom checkbox field
woocommerce_form_field( 'chosen_packing', array(
'type' => 'select',
'label' => __('Choose regular or gift-wrap packaging:', $domain ),
'class' => array( 'form-row-wide packing' ),
'options' => array(
'' => __("Select an option:", $domain),
'bag' => sprintf( __("Regular (free)", $domain), strip_tags( wc_price(0.00) ) ),
'box1' => sprintf( __("Gift-wrap (1): 0,50€", $domain), strip_tags( wc_price(0.50) ) ),
'box2' => sprintf( __("Gift-wrap (2): 1,00€", $domain), strip_tags( wc_price(1.00) ) ),
'box3' => sprintf( __("Gift-wrap (3): 1,50€", $domain), strip_tags( wc_price(1.50) ) ),
'box4' => sprintf( __("Gift-wrap (4): 2,00€", $domain), strip_tags( wc_price(2.00) ) ),
'box5' => sprintf( __("Gift-wrap (5): 2,50€", $domain), strip_tags( wc_price(2.50) ) ),
'box6' => sprintf( __("Gift-wrap (6): 3,00€", $domain), strip_tags( wc_price(3.00) ) ),
'box7' => sprintf( __("Gift-wrap (7): 3,50€", $domain), strip_tags( wc_price(3.50) ) ),
'box8' => sprintf( __("Gift-wrap (8): 4,00€", $domain), strip_tags( wc_price(4.00) ) ),
'box9' => sprintf( __("Gift-wrap (9): 4,50€", $domain), strip_tags( wc_price(4.50) ) ),
'box10' => sprintf( __("Gift-wrap (10+): 5,00€", $domain), strip_tags( wc_price(5.00) ) ),
),
'required' => true,
), $chosen );
echo '</th><td>';
}
// 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 = __("Regular (free)", $domain);
$cost = 0.00;
} elseif ( $packing_fee === 'box1' ) {
$label = __("Giftwrap (1)", $domain);
$cost = 0.50;
} elseif ( $packing_fee === 'box2' ) {
$label = __("Giftwrap (2)", $domain);
$cost = 1.00;
} elseif ( $packing_fee === 'box3' ) {
$label = __("Giftwrap (3)", $domain);
$cost = 1.50;
} elseif ( $packing_fee === 'box4' ) {
$label = __("Giftwrap (4)", $domain);
$cost = 2.00;
} elseif ( $packing_fee === 'box5' ) {
$label = __("Giftwrap (5)", $domain);
$cost = 2.50;
} elseif ( $packing_fee === 'box6' ) {
$label = __("Giftwrap (6)", $domain);
$cost = 3.00;
} elseif ( $packing_fee === 'box7' ) {
$label = __("Giftwrap (7)", $domain);
$cost = 3.50;
} elseif ( $packing_fee === 'box8' ) {
$label = __("Giftwrap (8)", $domain);
$cost = 4.00;
} elseif ( $packing_fee === 'box9' ) {
$label = __("Giftwrap (9)", $domain);
$cost = 4.50;
} elseif ( $packing_fee === 'box10' ) {
$label = __("Giftwrap (10+)", $domain);
$cost = 5.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( __( "<strong>Packaging</strong> is a required field.", "woocommerce" ), 'error' );
}
Excuse my linguistic mistakes, english is not my native language.