phpjquerywordpresswoocommerceshipping-method

Hide checkout shipping fields section for specific shipping method in WooCommerce


Someone asked the following question that I have answered. Then he delete it. So I publish the question and my answer back as this can be useful for the community:

In WooCommerce, I am trying to update a checkbox form dynamically without reloading the checkout page. I have 2 shipping methods: "Delivery" and "Collect". I am trying to only disable the shipping address section (with the "ship to another address if chosen method is collect" checkbox option) and all shipping fields.

First I tried this:

add_action( 'woocommerce_after_shipping_rate', 'carrier_custom_fields', 30, 2 );
function carrier_custom_fields( $method, $index ) {
    if( ! is_checkout()) return; // Only on checkout page

    $customer_carrier_method = 'local_pickup:1';


    if( $method->id != $customer_carrier_method ) return; // Only display for "local_pickup"

    $chosen_method_id = WC()->session->chosen_shipping_methods[ $index ];

    // echo $chosen_method_id;

    // If the chosen shipping method is 'legacy_local_pickup' we display
    if($chosen_method_id == $customer_carrier_method ):

        add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false');

    else :
        add_filter( 'woocommerce_cart_needs_shipping_address', '__return_true');


    endif;

}

Then I tried this:

add_action( 'woocommerce_shipping_method_chosen', 'check_if_local_pickup', 10, 1 );
function check_if_local_pickup( $chosen_method ) {
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = $chosen_methods[0]; 
    if ($chosen_shipping == 'local_pickup:1') { 
        add_filter( 'woocommerce_ship_to_different_address_checked', '__return_false' );
        add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false');
        return true;
    }
    else
    {
        add_filter( 'woocommerce_cart_needs_shipping_address', '__return_true');
        return true;

    }
} 

Both of them doesn't work.

How to hide checkout shipping fields section for specific chosen shipping method in WooCommerce?


Solution

  • PHP is not the way as this an event on a "client side" (not on "server side"), so it requires to use jQuery. So to hide shipping fields section for a specific shipping method, you will use the following:

    // Auto Show hide checkout shipping fields section based on chosen shipping methods
    add_action( 'wp_footer', 'custom_checkout_field_script' );
    function custom_checkout_field_script() {
        // Only on checkout page
        if( is_checkout() && ! is_wc_endpoint_url() ):
    
        // HERE below define your local pickup shipping method
        $local_pickup = 'local_pickup:1';
    
        // Jquery code start
        ?>
        <script>
            jQuery(function($){
                var a = 'checked',      
                    b = 'input#ship-to-different-address-checkbox', 
                    c = 'input[name^="shipping_method"]',   
                    d = '<?php echo $local_pickup; ?>',     
                    e = c + ':' + a
                    f = 'div.woocommerce-shipping-fields,' + b;
    
                // 1. On load: when the chosen shipping method is our defined shipping method
                if( $(e).val() === d ) {
                    // Hide shipping fields section
                    $(f).hide(); 
                }
    
                // 2. On shipping method "change" (Live event)
                $( 'form.checkout' ).on( 'change', c, function() {
                    // When the chosen shipping method is our defined shipping method
                    if( $(e).val() === d ) {
                        // if the checkbox is checked, uncheck it first
                        if ( $(b).prop(a) ) {
                            $(b).click();
                        }
    
                        // Hide shipping fields section
                        $(f).hide();
                    } else if ( $(e).val() !== d ) {
                        // show closed shipping fields section with (unchecked checkbox)
                        $(f).show();                    
                    }
                });
            });
        </script>
        <?php
        endif;
    }
    

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

    Related: How to make ship to different address checked when using Free Shipping and Flat Rate?