My Courses > CustomizeWoo > Module 5 > Lesson 06: Edit Checkout Fields

Edit Checkout Fields

MARK LESSON AS COMPLETE

Editing the checkout fields is one of the most common customization. Here’s why you get a dedicated video lesson on it.

Video

Please note: English captions are enabled by default (click on “CC” in the video player to disable). Also, you can click on the “gear” icon to manage quality and playback speed. Enjoy!

Sorry, this video is visible to logged in and fully registered students only.
If you already enrolled in this course, please LOG IN
Otherwise, please enroll in the FREE / PRO COURSE
For any other queries, feel free to get in touch

Related Snippets

WooCommerce: edit or translate “Shipping and Handling” on the Cart & Checkout page

WooCommerce: Edit “Returning Customer?” Message @ Checkout

WooCommerce: Edit “Have a Coupon?” Message @ Cart & Checkout

WooCommerce: How to Remove “What is PayPal?” @ Checkout

WooCommerce: How to Add a Custom Checkout Field (PHP)

WooCommerce: Change Input Field to Textarea @ Checkout

25 thoughts on “Edit Checkout Fields

  1. I am trying to disable the UPS option for just the “Next Day Air” because UPS is not offering this and it confuses clients who select it. Is there a clean way to do this without recoding the UPS shipping plugin? I am noticing that the site I am working on has a custom plugin to extend UPS plugin to get live rates. Any insight would be very helpful on how to achieve disabling one of the several UPS shipping options.

    1. Hi Sam! Your UPS plugin should have a setting where you can enable/disable rates. If that’s not the case, switch to the official UPS plugin for WooCommerce and you’ll get that. Hope this helps

      1. This shop I am working with has been around for some time now and there is a custom plugin written to extend the UPS shipping options. I am proud to share that I handled the challenge using a function in the child-theme functions.php and a hook for the checkout to echo in some jQuery and hide just the ‘Next Day Air’ option. Here’s my code:

        // Add a jQuery function through a hook on the check out page 
        add_action( 'woocommerce_after_cart', 'hide_UPS_Option');
        function hide_UPS_Option() {
         echo '
        $(document).ready(function(){
        $("li:contains(Next Day Air)").hide();
        });
        ';
        }
        
        1. Ah ok cool

          1. Of course today I got an email that it is still showing up on certain pages for products. It has me scratching my head.

            1. Will adding a priority of “,1);” at the end of the ADD_ACTION fix that?

              1. No, it won’t, jQuery is called correctly. I guess that happens because your JS script is not dynamic e.g. it does not reload once the Checkout page updates shipping rates. That’s why I much prefer the option-way

  2. Hi Rodolfo, I managed to add a custom billing field. Yay! Definitely no more need for the Checkout Field Editor after this tutorial.

    add_filter( 'woocommerce_checkout_fields' , 'add_billing_email_field_checkout' );
    
    function add_billing_email_field_checkout( $fields ) {
         $fields['billing']['billing_email'] = array(
            'label'     => __('Email', 'woocommerce'),
        'placeholder'   => _x('e.g. name@domain.com', 'placeholder', 'woocommerce'),
        'required'  => true,
        'class'     => array('form-row-wide'),
        'clear'     => true,
        'priority'  => 25
         );
    
         return $fields;
    }
    1. Excellent!

  3. it worked great,

    add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
    
    // Our hooked in function - $address_fields is passed via the filter!
    function custom_override_default_address_fields( $address_fields ) {
         $address_fields['address_1']['required'] = true;
        $address_fields['address_1']['placeholder'] = 'Put your Address here the whole thing buddy!';
    
         return $address_fields;
    }
    
    1. Ahah lol, well done!

    2. I need to change the text type to dropdown but woocommerce default is given as text how can i do it?

  4. Thank you, Rodolfo! Step by step I learn how to modify my checkout fields. Now: I know how to change conditionally labels and placeholders in the checkout page if the “music” category is in the cart. But how to assign OTHER labels and placeholders IF ANOTHER CATEGORY is in the cart (let’s say “clothing”), but “music” or “any other categories” are NOT IN CART?

    1. Well done Marcel 🙂 All you need is to implement an “IF – ELSEIF – ELSE” statement (https://www.php.net/manual/en/control-structures.elseif.php). Basically you first check on something, then if that’s false you check on something else, then if all the previous ones are false you find yourself in the last “ELSE” statement. Do some tests, share your snippets, and let me know 🙂

  5. Hello again, Rodolfo!

    We learned from you how to remove or add a checkout field. My question is if is possible to apply the Conditional Logic rules on the checkout area, also. As usual, I hope the answer will be positive, but I just need your confirmation, especially if the custom fields on the checkout could be shown based on the product category. Thank you!

    1. Marcel, thanks for your comment! And it’s a good one. The answer is – always – “yes that’s possible”.

      Inside the filter trigger function, you could use the “foreach” section contained in this snippet: https://businessbloomer.com/woocommerce-check-product-category-cart/. If the category is in the Cart, you would keep going and return the new field. If not, you would return the old fields.

      Give it a go and let me know 🙂

      1. Thank you, Rodolfo, for the guidance. I followed your advice and I was able to make my function to work on the checkout area just for a product category (“music” in my case), but not for all product categories. If the “music” product category OR “music” and another product category are in the cart, all work as expected. If “music” is NO MORE in the cart but another product category is there, I receive this warning on the checkout page: Invalid argument supplied for foreach() in E:\xampp\htdocs\site2\wp-content\plugins\woocommerce\includes\class-wc-checkout.php on line 267.
        Also, the checkout fields are not there anymore. Please guide me!

        Here is the snippet I wrote:

        /**
         * @snippet       Check if "music" Product Category is in the Cart - WooCommerce
         */
         
        add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
        function custom_override_checkout_fields( $fields ) {
        // Set $cat_in_cart to false
        $cat_in_cart = false;
        // Loop through all products in the Cart        
        foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
         
            // If Cart has category "music", set $cat_in_cart to true
            if ( has_term( 'music', 'product_cat', $cart_item['product_id']) ) {
                $cat_in_cart = true;
                break;
            }
        }
           
        // Unset Order Comments if category "music" is in the Cart      
        if ( $cat_in_cart ) {
        	unset($fields['order']['order_comments']);
            return $fields;
        	}
        }
        1. Hello Marcel 🙂

          So, take a look at this:

          return $fields

          If your category is in the Cart, you give $fields back to the server – but if NOT, you give nothing back. That line must be outside the conditional, and you unset fields only inside:

             if ( $cat_in_cart ) {
                unset($fields['order']['order_comments']);
             }
             return $fields;
          }
          

          Makes sense? The goal of a filter function is to always give back (“return”) the variable.

          1. Hello Rodolfo. Done! But now, I would like to change “Billing details” text if a certain product category is in the cart.
            First, I tried just to change the “Billing details” text, and it works. Here is the snippet:

            function wc_billing_field_strings( $translated_text, $text, $domain ) {
                switch ( $translated_text ) {
                    case 'Billing details' :
                        $translated_text = __( 'MY OWN TEXT', 'woocommerce' );
                        break;
                }
                return $translated_text;
            }
            add_filter( 'gettext', 'wc_billing_field_strings', 20, 3 );

            The problem is if I try to change the text only if the “music” product category is in the cart. It seems I have a problem. Here is the snippet I used:

            /**
             * @snippet  Change "Billing details" text if "music" Product Category is in the Cart - WooCommerce
             */
            add_filter( 'gettext', 'wc_billing_field_strings', 20, 3 );
            function wc_billing_field_strings( $translated_text, $text, $domain ) {
            // Set $cat_in_cart to false
            $cat_in_cart = false;
            // Loop through all products in the Cart        
            foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
              
                // If Cart has category "music", set $cat_in_cart to true
                if ( has_term( 'music', 'product_cat', $cart_item['product_id']) ) {
                    $cat_in_cart = true;
                    break;
                }
            }
                
            // Change "Billing details" text if "music" product category is in the cart   
            if ( $cat_in_cart ) {
                  switch ( $translated_text ) {
                    case 'Billing details' :
                        $translated_text = __( 'Billing Info', 'woocommerce' );
                        break;
               }
               return $translated_text;
            }

            I made the exact same steps I used to unset order comments, I changed the filter, the function, and instead “return $fields” I used “return $translated_text”. Where I am wrong? Thank you!

            1. You’re missing another “}” before the return call maybe?

              1. Nope. This is the third day I sweat, looking for a solution. Maybe translating a text is not compatible with the conditional product category in the cart?
                Just to remember what I try: I want to translate “Billing details” text if the “music” product category is in the cart.
                Here is the snippet, with all brackets in place:

                add_filter( 'gettext', 'wc_billing_field_strings', 20, 3 );
                function wc_billing_field_strings( $translated_text, $text, $domain ) {
                // Set $cat_in_cart to false
                $cat_in_cart = false;
                // Loop through all products in the Cart        
                foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
                   
                    // If Cart has category "music", set $cat_in_cart to true
                    if ( has_term( 'music', 'product_cat', $cart_item['product_id']) ) {
                        $cat_in_cart = true;
                        break;
                    }
                }
                     
                // Change "Billing details" text if "music" product category is in the cart   
                	if ( $cat_in_cart ) {
                      switch ( $translated_text ) {
                        case 'Billing details' :
                            $translated_text = __( 'Billing Info', 'woocommerce' );
                            break;
                   }
                   return $translated_text;
                		}
                }

                Look what errors I have with this code:
                Fatal error: Uncaught Error: Call to a member function get_cart() on null in E:\xampp\htdocs\site2\wp-content\themes\generatepress_child\functions.php:19 Stack trace: #0 E:\xampp\htdocs\site2\wp-includes\class-wp-hook.php(286): wc_billing_field_strings(‘Primary Menu’, ‘Primary Menu’, ‘generatepress’) #1 E:\xampp\htdocs\site2\wp-includes\plugin.php(208): WP_Hook->apply_filters(‘Primary Menu’, Array) #2 E:\xampp\htdocs\site2\wp-includes\l10n.php(182): apply_filters(‘gettext’, ‘Primary Menu’, ‘Primary Menu’, ‘generatepress’) #3 E:\xampp\htdocs\site2\wp-includes\l10n.php(250): translate(‘Primary Menu’, ‘generatepress’) #4 E:\xampp\htdocs\site2\wp-content\themes\generatepress\functions.php(49): __(‘Primary Menu’, ‘generatepress’) #5 E:\xampp\htdocs\site2\wp-includes\class-wp-hook.php(286): generate_setup(”) #6 E:\xampp\htdocs\site2\wp-includes\class-wp-hook.php(310): WP_Hook->apply_filters(NULL, Array) #7 E:\xampp\htdocs\site2\wp-includes\plugin.php(465): WP_Hook->do_action(Array) #8 E:\xampp\htdocs\site2\wp-settings.php(509) in E:\xampp\htdocs\site2\wp-content\themes\generatepress_child\functions.php on line 19

                Fatal error: Uncaught Error: Call to a member function get_cart() on null in E:\xampp\htdocs\site2\wp-content\themes\generatepress_child\functions.php:19 Stack trace: #0 E:\xampp\htdocs\site2\wp-includes\class-wp-hook.php(286): wc_billing_field_strings(‘Error occurred …’, ‘Error occurred …’, ‘default’) #1 E:\xampp\htdocs\site2\wp-includes\plugin.php(208): WP_Hook->apply_filters(‘Error occurred …’, Array) #2 E:\xampp\htdocs\site2\wp-includes\l10n.php(182): apply_filters(‘gettext’, ‘Error occurred …’, ‘Error occurred …’, ‘default’) #3 E:\xampp\htdocs\site2\wp-includes\l10n.php(250): translate(‘Error occurred …’, ‘default’) #4 E:\xampp\htdocs\site2\wp-includes\class-wp-recovery-mode.php(177): __(‘Error occurred …’) #5 E:\xampp\htdocs\site2\wp-includes\class-wp-fatal-error-handler.php(45): WP_Recovery_Mode->handle_error(Array) #6 [internal function]: WP_Fatal_Error_Handler->handle() #7 {main} thrown in E:\xampp\htdocs\site2\wp-content\themes\generatepress_child\functions.php on line 19
                Please guide me where I am wrong? Thank you!

                1. Ok Marcel, you have 3 errors.

                  First of all, “gettext” runs on every page. Even on the admin ones. Therefore, your code looks for a WooCommerce Cart which does not exist on every page… the object only exist on the frontend and given that you want to translate something on the Checkout Page only, you should wrap the whole function into a conditional “if ( is_checkout() ) { }”

                  Second, there is a missing “}” to close the switch

                  Third, “return $translated_text” should be the very last thing, outside the “{ }”.

                  Here’s the correct code:

                  add_filter( 'gettext', 'wc_billing_field_strings', 20, 3 );
                  
                  function wc_billing_field_strings( $translated_text, $text, $domain ) {
                  	
                  	if ( is_checkout() ) {
                  		
                  		// Set $cat_in_cart to false
                  		$cat_in_cart = false;
                  		
                  		// Loop through all products in the Cart        
                  		foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
                  			// If Cart has category "music", set $cat_in_cart to true
                  			if ( has_term( 'music', 'product_cat', $cart_item['product_id']) ) {
                  				$cat_in_cart = true;
                  				break;
                  			}
                  		}
                  
                  		// Change "Billing details" text if "music" product category is in the cart   
                  		if ( $cat_in_cart ) {
                  			switch ( $translated_text ) {
                  				case 'Billing details' :
                  					$translated_text = __( 'Billing Info', 'woocommerce' );
                  					break;
                  			}
                  		}
                  		
                  	}
                  	
                  	return $translated_text;
                  	
                  }
                  
                  1. Thank you, Rodolfo. It works exactly how you said. Please tell me if I could use “gettext” bassed on the hreflang tags. I am sure yes, but just need a little hint from your side.

                    1. Cool! In regard to hreflang, it depends on your multilanguage plugin – you’d need to find their conditional tags and see if they work with gettext. Do some tests and let me know

Questions? Feedback? Support? Leave your comment now!
_____

If you are writing code, please wrap it between: [php]code_here[/php]

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