You ask, i write! This post has been asked by sidharh in my other article about how to “Add a checkout field in WooCommerce only for specific roles“.

This time instead, we will hide checkout fields based on the products contained into your cart. you asked to add them instead to hide them, but it’s a lot quicker to add them all, and then hide them when they are not needed.

Let’s start!

First of all, install and activate Checkout Field Editor. This is not a required step, if you do not have the plugin and do not want to purchase it you can add the field by yourself following this tutorial.

Create all the new fields you need for the shipping for or the billing for or also additional fields. Also, be sure to have a list of all the products ID you need to use in your code to hide specific fields. If you don’t know how to get the product ID, read this tutorial.

Now you are ready to write some code. Open your functions.php file located in wp-content/themes/your-theme-name/ and add this code at the end of the file:

In this code, i hide the billing and shipping company field only if the product ID 70 is in the customer cart.

This is a very simple rule, obviously you can create very complex rules too, like hide fields only if there’s a product, but not another one, or hide a field if there are 2 or more products into the cart or anything else you can think about.

50 replies
  1. villaceque Jonathan
    villaceque Jonathan says:

    Hi,

    I just use your snippets code, 1 month ago and it works.
    But now with somes updated i think… it doesn’t work, i just use more products :

    function conditional_checkout_fields_products( $fields ) {
        $cart = WC()->cart->get_cart();
    
        foreach ( $cart as $item_key => $values ) {
            $product = $values['data'];
    
            if ( $product->id ==  2624 || 2630 || 2634 || 2636 || 2637 || 2814 ) {
                  unset( $fields['billing']['aut1'] );
                  unset( $fields['billing']['aut2'] );
                  unset( $fields['billing']['aut3'] );
            }
        }
    
        return $fields;
    }
    add_filter( 'woocommerce_checkout_fields', 'conditional_checkout_fields_products' );
    

    it’s a good snippet ? or it’s the plugin updated that is wrong ?
    I put it in the functions.php.
    Thanks for your help.

    PS: Nice website 😉

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi! Thanks for reading!

      if ( $product->id == 2624 || 2630 || 2634 || 2636 || 2637 || 2814 ) {

      You can’t do this. You should do

      if ( $product->id == 2624 || $product->id == 2630 [etc.] ) {

      Reply
  2. sidharth
    sidharth says:

    Thanks Nicola,

    I tried this code snippet on some products with some tweak and it worked well. This was really helpful.

    I having a bug/error on a site using woocommerce. On each product page there is a section to leave a review, but the user must be logged in to comment (which I want)

    So, when a user is not logged in, they get the message “You must be logged in to post a comment” and the log in link goes to https://www.mysite.com/wp-login….. and redirects back to the previous page. I do not want any of my users seeing the wordpress login. I want them to go to woocommerce login page https://www.mysite.com/my-account and then keep the redirect in place – redirected back to the page they were on once logged in.

    I know this is something to do with classes {must-login-in} & {logged-in-as}.

    .sprintf( __( 'You must be <a href="%s" rel="nofollow">logged in</a> to post a comment.' ), get_permalink(get_option('woocommerce_myaccount_page_id'))).'';

    If you can write an article on woocommerce redirect link and how to generate woocommerce my account URL by using the woocommerce_myaccount_page_id.

    Reply
  3. Dave S
    Dave S says:

    Great article. I’m new at WooCommerce and would like to know how you would HIDE form fields if… all of the products in the cart contained the same TAG… If any product in the cart did not contain the TAG, then the form field should SHOW. Thanks for your help.

    Reply
  4. MC
    MC says:

    Great tip, works great! Except… Trying to remove a field that was created using Checkout Field Editor under a tab “Additional Fields”…

    Your unset tip works for [billing] .. and [shipping] … not sure how to trigger it for fields created under ‘additional’ tab since it’s not a [billing] [shipping] [order] or [account]…

    Any insight? Thanks!

    Reply
      • Nicky
        Nicky says:

        Have the same problem like many before, I cannot target the ‘additional’ fields?

        Im using the “WooCommerce Checkout Field Editor” plugin, and simply cannot “target those fields”
        Having the same problem with fields inserted by the ”
        WooCommerce Order Delivery” plugin (makes fields under #wc-od)

        Anyone has a soloution to this?

        Reply
    • Jenne
      Jenne says:

      I am looking for the ability to ‘hide’ the additional fields created and ‘show’ others. For instance, I wouldn’t ask the Exhibitors the same questions as the public…

      Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi Jenne,
      to do that you need to change the if on line 13 with this code:

      if ( has_term( 'category-slug', 'product_cat', $product->id ) ) {
      

      Replace category-slug with the category you want to check.

      Reply
  5. Mike
    Mike says:

    Nicola,

    Thank you so much. This is basically what I’ve been looking for for the past couple of hours and I’m 90% there.

    I am able to exclude certain fields when a specific product is added. However if I add another product to the cart that requires those fields they are still hidden. Is there a way to turn this off in this instance?

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi Mike,
      to do that you i would check each product ID to be different than the one you don’t want to hide the fields for. Then before to check the ID again (the line where you check if it’s == to 70, check also if it’s in an array with the ones you don’t want to hide. If it’s there, then show the fields, otherwise not.

      If you require assistance with this and would like to explore this further you can seek help from an Affiliated Woo Worker or post a job on Codeable, I have provided links to these below.

      Affiliated Woo Workers
      Codeable

      Have a great week!

      Reply
      • Mike
        Mike says:

        Nicola,

        Thanks for the response. Certainly beyond my skill level.

        I will check out those two links and see if I can get some assistance from a pro. Thanks again.

        Reply
  6. Florian
    Florian says:

    Hi Nicola,

    I add a field with wooCommerce add-on. It is a gift message with a text area for a given price. As I don’t sell only gift product, I want to hide the “gift message” field when it’s not a gift.

    I tried to replace billing by “additional” and after “gift_message” but it’s not working! Do you have any suggestion?

    P.S. thanks a lot for your amazing website! Very useful and easy to understand! If you’re not, you should become a professor 🙂

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi Florian,
      in the snippet above, add this code after line 8: var_dump( $fields ).

      This code will show all the checkout fields show on the page, so you can find which index to use to hide the gift message.

      P.S. Thanks! I’m glad you find it useful 🙂

      Reply
  7. Richard
    Richard says:

    I have a scenario that I wondered if you could help with relating to this code.

    I have one product (a Fan Club Membership) that requires additional fields to be visible on Checkout. The rest of my products don’t require these fields.

    So I am using the above code to hide these fields for the rest of the products.

    However, it doesn’t take into account if a user adds BOTH the Fan Club Membership AND another product. It removes the fields in this instance, but it should not.

    Any idea how I can manipulate this code to work for this scenario?

    Many thanks,

    Richard

    Reply
  8. Jijig
    Jijig says:

    Hi,

    I tried the code and it works for all default fields ( billing, shipping, order notes), but it does not work for additional fields that are added by me.

    I use this code:
    …. unset( $fields[‘additional’][‘additional_field_753’] ); …

    I have tried with code “var_dump( $fields );” to see the fields on my checkout page, but the additional fields that are created by me with the plugin just don’t show up there. So I guess it does not see my fields.

    How can I hide them?

    Thanks in advance!

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      That is most probably caused by the priority of the filter.

      Make sure that it’s higher than 10, like this:

      add_filter( 'woocommerce_checkout_fields', 'conditional_checkout_fields_products', 20 );
      

      Or more than 20 if needed.

      Reply
      • DigitalMako
        DigitalMako says:

        Hey Guys,

        Strolling through the thread looking for a solution to this same problem. I’ve tried all of the recommendations in this thread, but can’t seem to hide the additional fields that I created using the “additional fields” section.

        Here’s the code that I’m using:

        /**
        * Hides checkout fields based on the products in the cart
        *
        * @param array $fields
        * @return array
        */
        function conditional_checkout_fields_products( $fields ) {
        $cart = WC()->cart->get_cart();

        foreach ( $cart as $item_key => $values ) {
        $product = $values['data'];

        if ( $product->id == 35 ) {
        unset( $fields['billing']['billing_phone'] );
        unset( $fields['additional']['additional_field_deliverydays'] );
        }
        }

        return $fields;

        }
        add_filter( ‘woocommerce_checkout_fields’, ‘conditional_checkout_fields_products’, 50 );

        Need to be able to hide a field that we created called “delivery days”, in addition to a few other fields that were created under the additional fields section.

        Thanks in advance for any assistance that you can provide!

        Regards

        Reply
  9. ilembke
    ilembke says:

    Hi,
    this looks pretty interesting. I have another problem: I just want to hide/display a css class when a certain pro/cat is in the cart!!

    Reason: My client has klarna as paymethod and they have there own checkout page after the cart-page with a link to regular checkout from woocommerce. Now they have a new product-category and they want to deactivate/skip klarna for that. I just created a new button in the cart.php with a own class and the link directly to the regualar checkout.

    Its a pretty dirty solution, but any idea if that is possible with your script? Thanks for your help!!!

    Reply
  10. Max
    Max says:

    I’m struggling with something this problem.

    When a coupon is applied I need to show the order comments as a required field.
    When no coupon is used I want to hide the order comments.

    I can hide it with:
    unset( $fields[‘order’][‘order_comments’] );
    but the order comments are still required.

    I just assumed that unsetting a field also made the requirement obsolete.

    Any pointers for this scenario?

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi Max,
      you can use $fields['order']['order_comments']['required'] = false; to make that field not required.

      By default, it is not required though, so this code I suggested may not work. It depends on how you make it required.

      Reply
      • Max
        Max says:

        Hi Nicola

        I need something like this:

        Coupon code applied
        – Show order comments
        – Order comments = required filed

        No coupon applied
        – Hide order comments
        – Order comments = NOT required (which I assumed followed the hiding/unsetting)

        The setup I have now is that I make the order comment required as a default. And when no coupon is present I have a snippet that hides it:
        unset( $fields[‘order’][‘order_comments’] );
        add_filter( ‘woocommerce_enable_order_notes_field’, ‘__return_false’ );

        I was assuming that unsetting and hiding a field would also ignore the requirement.

        Reply
  11. Max
    Max says:

    Thanks Nicola, here is the snippet:
    https://gist.github.com/Dudikowski/f53b4e7ed4251dd90400d1f1ea94c65c

    I dont know how much of this code is useful for a working solution though. I came to this setup after making a bad assumption. I thought that unsetting a field would make it completely out of the picture.

    The default settings for the checkout fields
    If no coupon code was used we hide the order comments, but the required setting from #1 is still valid

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      I don’t think that is going to work.

      What I would do is:

      • Make notes NOT required by default
      • Add a JS that makes the notes required or not based on the coupon, when the page loads
      • Use the action woocommerce_before_checkout_process to make sure that the note is NOT empty when it is required
      • From that action, return true or false to eventually stop the checkout
      Reply
  12. Nermin
    Nermin says:

    I want to add custom content in spesific product pages not all of them , I have added the following code but it didn’t work, please advice

    function iconic_output_engraving_field() {
    
    global $product;
    global $woocommerce;
    
    if ( $product->id !== 411 || $product->id !== 412 ){
        return;
    }
    
    ?>
    <div class="iconic-engraving-field">
        <label for="iconic-engraving"><?php _e( 'Gluten Free', 'iconic' ); ?></label>
        <input type="checkbox" id="iconic-engraving" name="iconic-engraving" value="Gluten Free">
    </div>
    <?php
    
    }
    
    add_action( 'woocommerce_before_add_to_cart_button', 'iconic_output_engraving_field', 10 );
    
    Reply
  13. Tim
    Tim says:

    How can i use this in reverse?

    I mean i want to hide all the fields and when a specific product is in checkout i want this field to be showed?

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      Hi Tim,
      instead of using $product->id == 70 use $product->id != 70.

      In the first case it means that the product ID has to be equal to 70, in the second case it means that it must be different.

      Reply
  14. uschi
    uschi says:

    Hi,
    please how can I hide only a Country in checkout billing or shipping adress is logged in user is not member of a Special Group? For example Bulgaria
    unset( $fields[‘billing’][‘billing_country][‘BG’] );
    does not work

    Reply
  15. Manish
    Manish says:

    Hello,
    I am trying to make a directory with free and paid listings.
    Is it possible that:-
    Only for the zero rated (free) product IDs in woocommerce, the ‘Proceed to Checkout’ button becomes / behaves as ‘Place Order’ button on the checkout page. (In short, can I skip the checkout page and go directly from ‘Proceed to Checkout’ to ‘Order confirmation page’.
    Normally users find the checkout page irritating when there is no payment involved.
    Many thanks for your time. Any help will be deeply appreciated.

    Kind Regards,
    Manish

    Reply
  16. Sheila
    Sheila says:

    Simply – it did not work for me 🙁
    I’ve tried it in an incognito window and 2 different browsers, and have cleared browser caches.

    Reply

Trackbacks & Pingbacks

  1. […] Hide checkout fields based on the products in the cart […]

  2. […] Here’s a tutorial from WooNinja Nicola Mustone on hiding checkout fields based on products in the cart. […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

You have to agree to the comment policy.

This site uses Akismet to reduce spam. Learn how your comment data is processed.