Make “Ship to different address” mandatory if specific products are in WooCommerce cart

I’m trying to add a snipped to activate the “Ship to other address” open by default, when a specific product is in the checkout.
I found Enable ‘Ship to a different address’ check box for specific products in Woocommerce related answer thread which is working perfectly!

However, it should not be possible to unselect the check box “Ship to other address”. If a specific product is in the checkout, then providing a different shipping address is required.

Goal: Gray-out the “Ship to other address” checkbox for those specific products.

I just changed in the code $products_ids = array(10800, 11907); to feet my needs.

I already tried to unhook the function but then the whole code does not work. So I’m searching the best way to gray-out that checkbox but keep the code above fully working.

Answer

If I have understood, you want to keep your code functionality, disabling the checkbox (so you can keep your current code).

You could remove the checkbox when checkbox is checked (using jQuery).

This can be done with this simple jQuery code:

add_action( 'template_redirect', 'cart_needs_shipping_address_js');
function cart_needs_shipping_address_js() {
    if( is_checkout() && ! is_wc_endpoint_url() ) :

    wc_enqueue_js( "jQuery( function($){
    var a = '#ship-to-different-address-checkbox';
    if( $(a).is(':checked') ) {
        $(a).remove(); // Remove checkbox
    } 
    });");
    endif;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

So when checkbox is checked you will get (for your defined products):

enter image description here


Or you could use the following (replacing your code), that will hide the shipping address checkbox for your specific products:

// Hide the checkbox (inline CSS) - Only on checkout page
add_filter( 'wp_head', 'shipping_address_checkbox_ccs' );
function shipping_address_checkbox_ccs() {
    if( is_checkout() && ! is_wc_endpoint_url() ) {
        ?><style>body.checkout-hide-checkbox #ship-to-different-address-checkbox { display:none; } body.checkout-hide-checkbox #ship-to-different-address label { cursor: default; }</style><?php
    }
}

// Conditional function
function mandatory_shipping_address(){
    $products_ids = array(10800, 11907);
    $found = $others_found = false;

    foreach ( WC()->cart->get_cart() as $cart_item ){
        if ( in_array( $cart_item['data']->get_id(), $products_ids ) ){
            $found = true;
        } else {
            $others_found = true;
        }
    }
    return $found && ! $others_found ? true : false;
}

// Conditionally Enable checkbox (checked)
add_filter( 'woocommerce_ship_to_different_address_checked', 'filter_cart_needs_shipping_address');
function filter_cart_needs_shipping_address( $checked ) {
    return mandatory_shipping_address() ? true : $checked;
}

// Conditionally Add a body class - Only on checkout page
add_filter( 'body_class', 'shipping_address_checkbox_body_class' );
function shipping_address_checkbox_body_class( $classes ) {
    if( is_checkout() && ! is_wc_endpoint_url() && mandatory_shipping_address() ) {
        $classes[] = 'checkout-hide-checkbox';
    }
    return $classes;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Note: You will need to use the jQuery code to avoid the shipping address to be shown or hidden by clicking on the checkbox label.

Leave a Reply

Your email address will not be published. Required fields are marked *