Conditionally hide Woocommerce checkout custom field based on free shipping

In WooCommerce, I am trying to hide one custom added field whenever "free delivery" is selected (automatic selection, based on order amount).

I was thinking that I found a solution with code below, but when I load a page on new (incognito) browser window, the field is present and if refresh it, the field is hidden again.

// Hide address field, when Free Shipping mode is selected
add_filter('woocommerce_checkout_fields', 'xa_remove_billing_checkout_fields');

function xa_remove_billing_checkout_fields($fields) {
    $shipping_method ='free_shipping:5'; // Set the desired shipping method to hide the checkout field(s).
    global $woocommerce;
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = $chosen_methods[0];

    if ($chosen_shipping == $shipping_method) {
        unset($fields['billing']['billing_field_432']); // Add/change filed name to be hide
    return $fields;

Any help is appreciated.

1 answer

  • answered 2018-03-14 01:17 LoicTheAztec

    As it's a live event, you need to use javascript/jQuery to make it work. Your "billing_field_432" has to be not required, because when field is hidden and trying to submit the order, will throw an error notice message for this custom checkout field.

    The code to show / hide that field based on 'free_shipping:5' Shipping method:

    // Conditional Show hide checkout fields based on chosen shipping methods
    add_action( 'wp_footer', 'conditionally_hidding_billing_custom_field' );
    function conditionally_hidding_billing_custom_field(){
        // Only on checkout page
        if( ! is_checkout() ) return;
        // HERE your shipping methods rate ID "Free shipping"
        $free_shipping = 'free_shipping:5';
                // Choosen shipping method selectors slug
                var sm  = 'input[name^="shipping_method"]',
                    smc = sm + ':checked',
                    cbf = '#billing_field_432_field',
                    ihc = 'input[name="hidden_check"]';
                // Function that shows or hide imput select fields
                function showHide( selector = '', action = 'show' ){
                    if( action == 'show' )
                        $(selector).show( 200, function(){
                            $(ihc).val('1'); // Set hidden field for checkout process
                        $(selector).hide( 200, function(){
                            $(ihc).val(''); // Set hidden field for checkout process
                    $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
                // Initialising: Hide if choosen shipping method is "Free Shipping" method
                if( $(smc).val() == '<?php echo $free_shipping; ?>' )
                    showHide( cbf, 'hide' );
                    $(ihc).val('1'); // Set hidden field for checkout process
                // Live event (When shipping method is changed): Show or Hide based on "Free Shipping" method
                $( 'form.checkout' ).on( 'change', sm, function() {
                    if( $(smc).val() == '<?php echo $free_shipping; ?>' )
                        showHide( cbf, 'hide' );
                        showHide( cbf );

    The code to add a custom checkout hidden input field to enable the "required" field option check process when 'billing_field_432' is not hidden:

    // Add a hidden input field for "required" option check process
    add_filter('woocommerce_checkout_fields', 'add_custom_hidden_input_field' );
    function add_custom_hidden_input_field( $fields ) {
        echo '<input type="hidden" id="hidden_check" name="hidden_check" value="">';
        return $fields;
    // Check custom checkout field "billing_field_432" when not hidden
    add_action('woocommerce_checkout_process', 'check_custom_field_checkout_process');
    function check_custom_field_checkout_process() {
        // Check if set, if its not set add an error.
        if ( isset( $_POST['hidden_check'] ) && $_POST['hidden_check'] && empty( $_POST['billing_field_432'] ) )
            wc_add_notice( __( 'Please enter something in "billing field 432".' ), 'error' ); // SET your custom error notice

    This code goes on function.php file of your active child theme (or theme). Tested and works.

    It's based on: Conditionally hide a Checkout field in WooCommerce based on chosen shipping

    As you are using free shipping method with a minimum order amount of "50" and hiding other shipping methods when "free shipping" is available. You should use this instead:

    // Unset checkout field based on cart amount for free shipping
    add_filter('woocommerce_checkout_fields', 'remove_checkout_billing_field_432', 999 );
    function remove_checkout_billing_field_432( $fields ) {
        if ( WC()->cart->cart_contents_total >= 50 ) {
            unset($fields['billing']['billing_field_432']); // Unset field
        return $fields;

    This code goes on function.php file of your active child theme (or theme). Tested and works.