Reputation:
I'm struggling with changing the shipping option selected default. The 'Free shipping' shipping option only shows up if the customer has the amount over $70 + in the cart. If the amount on the cart is less than $70 the shipping option will not show up on the shipping options.
If the customer has over $70 or more, the "Free shipping" option will show up and it should be a default selected shipping option.
I tried adding the following snippet but it seems not working for me or maybe there's a mistake on modifying the ID's(unsure).
add_action( 'woocommerce_before_cart', 'set_default_chosen_shipping_method', 5 );
function set_default_chosen_shipping_method(){
//
if( count( WC()->session->get('shipping_method_0')['rates'] ) > 0 ){
foreach( WC()->session->get('shipping_method_0')['rates'] as $rate_id =>$rate)
if($rate->method_id == 'free_shipping30'){
$default_rate_id = array( $rate_id );
break;
}
WC()->session->set('chosen_shipping_methods', $default_rate_id );
}
}
I got this snippet idea here
Thank you in advance!!
Upvotes: 4
Views: 3353
Reputation: 2377
I think this might be helpful as well. Using Javascript and JS checkout event checkout_init
I combined jQuery and Javascript because I only have limited knowledge with jQuery.
jQuery(document).ready(function($) {
$(document).on('init_checkout', function() {
const shippingOptions = document.querySelectorAll('#shipping_method input')
if(!shippingOptions && shippingOptions.length === 0) {
return
}
shippingOptions.forEach((shipping) => {
if(shipping.value.includes('free_shipping')) {
shipping.checked = true
const event = new Event('click');
dropdown.dispatchEvent(event);
}
})
});
});
Upvotes: 0
Reputation: 197
The answer given by @7uc1f3r does deselect free shipping if available, but also deselects other default shipping methods* if no free shipping is available, resulting in no shipping method being selected.
The following should only affect the default shipping method if there is a free shipping method available.
function select_free_shipping_by_default()
{
if ($rates = WC()->session->get('shipping_for_package_0')['rates']) {
foreach ($rates as $rate_id => $rate) {
if ($rate->method_id == 'free_shipping') {
WC()->session->set('chosen_shipping_methods', array($rate_id));
break;
}
}
}
}
add_action('woocommerce_before_cart', 'select_free_shipping_by_default', 10, 0);
Depending on your aesthetic, you could alternatively accomplish this without a the foreach
loop, though I accept this may be less legible (and would require PHP 7.4+ for the arrow function).
function select_free_shipping_by_default()
{
if ($rates = WC()->session->get('shipping_for_package_0')['rates']) {
if ($free = array_filter($rates, fn ($x) => $x->method_id == 'free_shipping')) {
WC()->session->set('chosen_shipping_methods', array_keys($free));
}
}
}
add_action('woocommerce_before_cart', 'select_free_shipping_by_default', 10, 0);
Tested on: WooComerce 8.3.1 | WordPress 6.4.3 | PHP 8.1.23
Hope this helps someone :)
* The default selection for shipping method is normally configured in the admin. The first item in drag/drop order of the shipping methods in the relevant shipping zone is selected by default (eg at /wp-admin/admin.php?page=wc-settings&tab=shipping&zone_id=1
).
Upvotes: 0
Reputation: 29614
Your code contains some mistakes
WC()->session->get('shipping_method_0')['rates']
with WC()->session->get( 'shipping_for_package_0')['rates']
if($rate->method_id == 'free_shipping30'){
with if ( $rate->method_id == 'free_shipping' ) {
So you get:
function action_woocommerce_before_cart() {
// NOT empty (get)
if ( count( WC()->session->get( 'shipping_for_package_0')['rates'] ) > 0 ) {
// Loop through
foreach ( WC()->session->get('shipping_for_package_0')['rates'] as $rate_id => $rate ) {
// For free shipping
if ( $rate->method_id == 'free_shipping' ) {
$default_rate_id = array( $rate_id );
break;
}
}
// Set
WC()->session->set( 'chosen_shipping_methods', $default_rate_id );
}
}
add_action( 'woocommerce_before_cart', 'action_woocommerce_before_cart', 10, 0 );
Upvotes: 5