Conditionally show / hide WooCommerce checkout fields

A group of shopping carts at a grocery store

44 thoughts on “Conditionally show / hide WooCommerce checkout fields

  1. Awesome snippet Caleb! Please note that it will work only with PHP versions > 4.0.1

    1. Good point. As long as it’s above WordPress’ requirement, all should be good: https://wordpress.org/about/requirements/.

  2. Hi Caleb,
    nice work! Would it also be possible to manipulate the checkout fields based on the country the user selected?

    1. Hey, thanks! I looked into adding this as an example, but there are some complications. You can get the shipping country using this line, and then set a conditional with it:

      $country = WC()->customer->get_shipping_country();

      However, the ‘woocommerce_checkout_fields’ hook that lets us remove checkout fields will not be run again when the shipping country is changed. So the page would have to be refreshed after changing the country.

      Possible ways around this?

      1. Force the page to refresh when the country is changed >.<
      2. Maybe use Javascript to hide the field rather than unsetting it.
  3. Awesome work Caleb. Came very handy today.

    Great with the different examples of how to use it with categories and even coupons.

    Thanks

  4. Hi, thank you for your great article. Is it possible to use “unset()” to delete a div in a woocommerce checkout?

    1. Can I use someting like this?

      function wc_ninja_remove_checkout_field( $fields ) {
      if ( ! wc_ninja_product_is_in_the_cart() ) {
      $( “#my_custom_checkout_field” ).remove();
      }

      return $fields;
      }
      add_filter( ‘woocommerce_checkout_fields’ , ‘wc_ninja_remove_checkout_field’ );

      1. Hey Andreas,

        Uhh, no, not quite. That looks like a mix between PHP and jQuery. This snippet should help you get started on this: https://docs.woothemes.com/document/woocommerce-checkout-add-ons-developer-docs/#section-4

  5. I used exactly that code and is working on my localhost… but i got a server error en production.

    1. I made this for PHP 5.3

    2. I made this por PHP 5.3

      function wc_ninja_product_is_in_the_cart() {
      global $woocommerce;
      $items = array( ’31’ );
      // Create array from current cart
      $cartitems = $woocommerce->cart->get_cart();
      // Count items in cart
      $itemcount = count( $cartitems );
      foreach($cartitems as $cartitem) {
      $productid = $cartitem[product_id];
      if(in_array($productid,$items)) {
      return true;
      } else
      {
      return false;
      }
      }
      }

      /**
      * Borra los campos si se cumplen las condiciones indicadas
      */
      function wc_ninja_remove_checkout_field( $fields ) {
      if ( ! wc_ninja_product_is_in_the_cart() ) {
      unset( $fields[‘billing’][‘billing_justify2’] );
      }

      return $fields;
      }
      add_filter( ‘woocommerce_checkout_fields’ , ‘wc_ninja_remove_checkout_field’ );

      1. Hi Pedro,

        First, I would suggest upgrading to at least PHP 5.4. That’s the minimum required version for WordPress and WooCommerce.

        But secondly, I think the issue with your code is some of the quotation marks. You have ‘smart quotes’ all of the place. With code, it is important to use the plain quotes you get when typing in a plain text editor. Try this instead: https://gist.github.com/WPprodigy/aa6b26dce224a43444bd

  6. Hi, I am new to wordpress. I want to hide approx. 10 fields if a product, id=55, is in the cart by itself.

    When I follow your “remove checkout field example” from above it works perfectly.

    At the “Setting Up the Conditions” sections after I add it to my theme functions.php I get the following error:

    Fatal error: Can’t use function return value in write context in E:\web\public_html\…\wp-content\themes\storefront-child\functions.php on line 47

    which is the first line of the following part of code:

    if ( ! empty( array_intersect( $ids, $cart_ids ) ) ) {
    return true;
    } else {
    return false;
    }

    Any help you could provide would be great.

    Thanks
    Roland

    1. Oops, this may be my fault. The code I wrote required PHP version 5.5. You can’t use empty() with a function in it’s parameter below PHP 5.5. You can read more about this here: http://www.php.net/manual/en/function.empty.php

      You could update your PHP version (recommended), or just change the code to:

      $search = array_intersect( $ids, $cart_ids );
      if ( ! empty( $search ) ) {
      return true;
      } else {
      return false;
      }

  7. Great article. What call would I make to see if a field has been checked to show another field.

    For example:

    Field Name: Add VAT (True / False Checkbox)

    If TRUE > Show Field VAT

    1. Hiding fields based on other fields requires a different approach. This comment kind of applies here as well: https://calebburks.com/conditionally-showhide-woocommerce-checkout-fields/#comment-16

      You will likely need to do this with Javascript. Something like this: https://docs.woothemes.com/document/woocommerce-checkout-add-ons-developer-docs/#section-4

      1. Thanks

  8. Hi

    How can I show a custom field based on the quantity products.

    ================
    Product QTY = 1

    Custom field:
    Text for Engraving

    ===============

    Product QTY = 3

    Custom fields:
    Text for Engraving 1
    Text for Engraving 2
    Text for Engraving 3
    ===============

    Thank you

    1. Is there a specific product that you want this quantity rule to apply to, or is this all product’s in the cart?

      If it is product specific, you can use the “Product Specific Conditional” from above. And then you can var dump the `$cart_product` variable to find how you can get it’s quantity. To get the whole cart’s quantity, `WC()->cart->cart_contents_count` should do the trick.

      However, I don’t think checkout fields are best for this. It would be much better and more user friendly to add a field on the product page instead: https://www.woothemes.com/products/product-add-ons/

      1. Hi Caleb

        Thank you for your reply;

        I need to use this with Event Tickets ( by Modern Tribe ) to capture the name and email of each attendee, when multiple tickets are bought in one transaction.

        When it was still called WooTickets, BuzzMedia created a one file add-on called Wootockets Attendee List which did the job perfectly. http://buzzwebmedia.com.au/wootickets-attendee-list/

        I tried the woocommerce product add-ons, but that didn’t work with the quantity field.

        1. Hi Schalk,

          Ahh yea, you would need to have the customer add each ticket individually with Product Addons.

          Another option could be to construct a Ninja Form and apply it to a product with this: https://www.woothemes.com/products/woocommerce-ninjaforms-product-addons/

          With the Ninja Forms Conditional Logic plugin, you could make it so a new name field appears on the product page with each quantity increase (you would want to create your own quantitiy field).

          1. Hi Caleb

            Your suggestion worked, but I used Gravity Forms Add Ons.
            https://www.woothemes.com/products/gravity-forms-add-ons/

            I made my product price $0
            Then created a Gravity form price field of $50
            And multiplied this by the number attendees selected.

            It all works perfectly, except for one thing:
            The stock level are always deducted with 1 item, even when 2, 3 or 4 attendees are selected. I can manually rectify this after each order that contain more than one attendee, but it would be nice to have it work right.

            Can I commission you to write a function which will make the quantity field read from the Gravity forms attendee value? And what will it cost?

            This is a product on the live site:
            http://events.moonstone.co.za/product/compliance-report-workshop-stellenbosch/

            Should you wish to complete a test purchase, i’ll just reverse it.

            This was also requested on Woo Ideas:
            http://ideas.woothemes.com/forums/133476-woocommerce/suggestions/6198245-woocommerce-gravity-forms-add-on-inventory

            Thank you,

          2. I’m not taking any custom work right now, but one of the Woo Experts should be able to help you with this: http://www.woothemes.com/experts/

  9. Just wanted to say THANKS for the snippet(s) and the walk through explanation. It really came in handy!

  10. Hi Caleb,

    Is there any way of setting a custom field to be required only if it appears on the checkout page? At the moment I’ve got a product that I’ve placed into a category and a field only appears on the checkout field if that product is in the cart. I want to make sure those fields are completed by the user as they are important information. However, if I set them to be required then when a person gets to the checkout they cannot complete the transaction because error checking is looking for those fields to be completed.

    1. Hey Mike,

      Hmm, I would think that this shouldn’t be an issue, as long as the field is unset correctly.

      I just tested by creating a custom required field, and then conditionally unsetting it. As far as I can tell, there is no error when completing checkout when the field has been removed.

      Maybe check the priority levels of your hooks and filters?

  11. Caleb,

    Do you know how I would create a conditional checkout if a specific payment method is selected?

    We want to remove the address & information fields for Cash or Check customers by using the Cash on Delivery payment method (for when customers are paying with cash at our physical shop). We need guest checkout disabled for other reasons, so that won’t work.

    So if when we select ‘Cash or Check’ payment method in Checkout, if it could conditionally remove all the contact boxes that’d be incredibly rad.

    Dan

    1. Similar to https://calebburks.com/conditionally-showhide-woocommerce-checkout-fields/#comment-16, the ‘woocommerce_checkout_fields’ hook does not get re-fired when the payment method changes at the moment. The best option here would be to use Javascript to remove / hide the fields from the DOM conditionally.

      It may be worth noting that the checkout flow is going to be changed in the future: https://github.com/woothemes/woocommerce/issues/10672. So gateways not requiring billing addresses won’t need to ask for one. I’d suggest maybe following that github issue 🙂

  12. Hello Caleb. Thank you very much for your article.

    I hope you can help me with my problem:

    I need add a new field in the checkout form when change the shipping method radio selector. So, I need to reload the checkout page.
    I spent more than 3 hours looking for how can I do this.

    Can you help me tell me where is the file to change to force to reload the page??

    Thank you very much

    1. Hi,

      I’m not entirely sure what the best option is for this. I think your better option would be to write some Javascript that will hide/show the field based on what shipping method is selected.

  13. Thanks for writing this article, Caleb.

    I was wondering if you might be able to help me with a slight modification… What I would like to do is completely prevent checkout if no products from a certain category are in the cart.

    So let’s say a customer is required to place a product from Category A in their cart in order to checkout — if the customer adds a product from Category B to their cart, but does not have a product from Category A in their cart, the proceed to checkout button is disabled. If a customer adds a product from both Category A and B, or even just a product from Category A, then the proceed to checkout button ill be enabled as per usual.

    I can’t quite get this to work for me, so any guidance in the right direction would be much appreciated, thanks.

    1. This is possible, but will take a different type of customization. Instead of just disabling the checkout button, you could maybe make the payment gateways unavailable or not provide any shipping methods.

      Just be sure to let customer’s know why they can’t checkout if they aren’t meeting the requirements.

      1. Thanks for that, Caleb.

        I will have to look at what I can do.

  14. Hi Caleb,
    First of all, congratulations for the code, its awesome.
    Its working fine, but i need to hide a field that is not inside the billing fields.
    Actually its a custom checkout field to select the delivery date. I’m using an external paid plugin called WooCommerce Delivery Slots.

    I tried to replace the the last part of the code

    unset( $fields[‘billing’][‘billing_phone’] );

    for

    unset( $fields[‘jckwds-fields’][‘jckwds-delivery-date’] );

    but does not work.

    Could you help me get this working?

    Thank you!
    Best regards,
    Fabiano

    1. This plugin is likely still adding it’s custom field to either the billing, shipping, account, or order section. So `$fields[‘jckwds-fields’]` is incorrect.

      To find the id of the field and what section it has been added to, you’ll need to look through the plugins code or contact the plugin authors.

  15. Hi Caleb

    I want to hide som divs on the checkout page if no coupon code was used. I’ve been googling all day for a solution to my problem and this looks like something that could work. I’m trying to read up on adding css but with my lack of knowledge it’s all guess work at the end.

    Can you show an example with inline css added to the false statement and I can take it from there?

    1. Hi

      Sorry for the multiple posts but I rearranged the checkout page so I no longer would need a css solution for this. Your tips here should probably do the trick.

      I need to hide the order_comments when no coupon is applied. I’ve tried to embed the snippet below (which works) into your snippets but I can’t make it stick.

      unset( $fields[‘order’][‘order_comments’] );
      add_filter( ‘woocommerce_enable_order_notes_field’, ‘__return_false’ );

      1. Hey,

        Sorry, but I can’t provide site customizations here. If it helps, this is how WooCommerce core checks if a coupon has been applied or not:

        https://github.com/woothemes/woocommerce/blob/master/templates/checkout/form-coupon.php#L27

  16. Hi Caleb,

    This is great but how would it work for a variable product or subscription?

    Cheers

    1. Variable and subscription products still have product IDs. There shouldn’t be a problem using the above code for those two items.

      I’m not 100% sure, but it may take a little more customization if you need to target a specific variation ID.

  17. Great tutorial. I looked all over for this as I have very limited coding skills. This was the only resource that helped me achieve what I wanted to achieve and it took way less lines of code than other snippets I found on github, which also didn’t work for my needs. The other snippets wouldn’t factor in subscription purchases that contained free trials. Thanks for this article!

  18. I’m using a Turnkey Linux Moodle appliance, and am planning to upgrade the appliance this summer, but right now it is stuck at PHP 3.4.11.1. I was told that it is not recommended to upgrade PHP alone, but to generate a whole new appliance, so I am stuck here for the time being. Would it be too much to ask for a reference as to how to “dial back” your code to work with this version of PHP? Everything works great except (created the custom fields) but the conditional part doesn’t do its thing. Or if that is too much to ask, would you have any (old) references I could look at to get this to work? Thank you.

  19. hi! I was looking for this for a really long time! Thanks God google finally gave me your post! thank you!
    And i have one question – how can i give a buyer a certain role by the product he has bought?

    1. That is something more along the lines of WooCommerce Memberships: https://www.woocommerce.com/products/woocommerce-memberships/

Leave a Reply

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

Please note that I cannot help with customization requests. Your comment will not be approved if asking for code help. Visit this page if you need assistance with code.