In this post, we have seen how we can make fields mandatory or optional on the Checkout page. However, sometimes you may want to make some of these fields optional only based on certain conditions, such as when a particular country or state has been selected while entering the address. An example of this would be when you want to make the Phone number and Company fields mandatory for all countries except a couple of them. In this article, let’s explore how to make fields optional in WooCommerce depending on the country or state selected.
How to make fields optional in WooCommerce depending on the country or state selected, by using a code snippet:
We will start by adding the following code in the functions.php file of our child theme:
/** * Option to mark either the Phone or Company field as required when a defined country/state has been selected. * Set any of the elements to false to leave it at its default behaviour. */ function ts_require_fields_option() { return array( 'mark_company_field_as_required' => true, 'mark_phone_field_as_required' => true, ); } /** * List of selected Country/State that would bypass the required parameter for the Phone/Company fields. */ function ts_selected_country_state() { /** * Use Country Codes or State Codes. You can go through the links below for reference on Country/State Codes. * https://www.catarinabras.co.uk/woocommerce-country-codes/ * https://www.scratchcode.io/list-of-country-code-and-state-code-for-woocommerce/ */ return array( 'country' => array( 'IN', 'US' ), 'state' => array( 'AP' ), ); } /** * Remove "(optional)" text from Company and Phone fields. */ function ts_remove_optional_text( $field, $key, $args, $value ) { // Do this on the checkout page and My account page. if ( ( is_checkout() || is_wc_endpoint_url( 'edit-address' ) ) && ( 'billing_phone' === $key || 'billing_company' === $key ) ) { if ( 'billing_phone' === $key && ! ts_require_fields_option()['mark_phone_field_as_required'] ) { return $field; } if ( 'billing_company' === $key && ! ts_require_fields_option()['mark_company_field_as_required'] ) { return $field; } $optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>'; $field = str_replace( $optional, '', $field ); } return $field; } add_filter( 'woocommerce_form_field', 'ts_remove_optional_text', 10, 4 ); /** * Make the Phone and Company fields required where necessary. */ function ts_make_fields_required( $fields ) { // Do this on the checkout page and My account page. if ( is_checkout() || is_wc_endpoint_url( 'edit-address' ) ) { if ( ts_require_fields_option()['mark_phone_field_as_required'] ) { $fields['billing_phone']['required'] = 0 === (int) sanitize_text_field( wp_unslash( $_POST['ts_require_billing_phone'] ) ) ? false : true; } if ( ts_require_fields_option()['mark_company_field_as_required'] ) { $fields['billing_company']['required'] = 0 === (int) sanitize_text_field( wp_unslash( $_POST['ts_require_billing_company'] ) ) ? false : true; } } return $fields; } add_filter( 'woocommerce_billing_fields', 'ts_make_fields_required', 10, 1 ); /** * Mark the Company/Phone fields as required dynamically. */ function mark_fields_as_required_dynamically( $checkout ) { $selected_countries = "'" . implode( "', '", ts_selected_country_state()['country'] ) . "'"; $selected_states = "'" . implode( "', '", ts_selected_country_state()['state'] ) . "'"; // Hidden fields for validation. if ( ts_require_fields_option()['mark_phone_field_as_required'] ) { echo '<input type="hidden" name="ts_require_billing_phone" id="ts_billing_phone" value="0">'; } if ( ts_require_fields_option()['mark_company_field_as_required'] ) { echo '<input type="hidden" name="ts_require_billing_company" id="ts_billing_company" value="0">'; } ?> <script type="text/javascript"> (function($) { const required = '<abbr class="required" title="<?php echo esc_attr__( 'required', 'woocommerce' ); ?>">*</abbr>', selected_countries = [<?php echo $selected_countries; ?>], selected_states = [<?php echo $selected_states; ?>], billing_phone_required = '<?php echo ( ts_require_fields_option()['mark_phone_field_as_required'] ? 'true' : '' ); ?>', billing_company_required = '<?php echo ( ts_require_fields_option()['mark_company_field_as_required'] ? 'true' : '' ); ?>'; function get_selected_country_by_user() { return $('.shipping_address').is(':visible') ? $('#shipping_country option:selected').val() : $('#billing_country option:selected').val(); } function selected_state_by_user() { return $('#billing_state option:selected').val(); } function ts_add_class_field(selector, action = '') { $(selector).removeClass('woocommerce-validated'); $(selector).removeClass('woocommerce-invalid woocommerce-invalid-required-field'); if ('mark_not_required' === action) { $(selector).removeClass('validate-required'); $(`${selector} label > .required`).remove(); return; } $(selector).addClass('validate-required'); $(`${selector} label > .required`).remove(); $(`${selector} label`).append(required); } function ts_mark_field() { setTimeout(function() { if ('true' === billing_phone_required) { ts_add_class_field('#billing_phone_field'); $('input#ts_billing_phone').val('1'); if (Array.isArray(selected_countries) && selected_countries.length > 0 && selected_countries.includes(get_selected_country_by_user())) { if (Array.isArray(selected_states) && selected_states.length > 0 && !selected_states.includes(selected_state_by_user())) {} else { ts_add_class_field('#billing_phone_field', 'mark_not_required'); $('input#ts_billing_phone').val('0'); } } } if ('true' === billing_company_required) { ts_add_class_field('#billing_company_field'); $('input#ts_billing_company').val('1'); if (Array.isArray(selected_countries) && selected_countries.length > 0 && selected_countries.includes(get_selected_country_by_user())) { if (Array.isArray(selected_states) && selected_states.length > 0 && !selected_states.includes(selected_state_by_user())) {} else { ts_add_class_field('#billing_company_field', 'mark_not_required'); $('input#ts_billing_company').val('0'); } } } }, 300); } ts_mark_field(); $('form.checkout').on('change', '#billing_country, #billing_state, #shipping_country, #ship-to-different-address-checkbox', function() { ts_mark_field(); }); })(jQuery); </script> <?php } add_action( 'woocommerce_after_order_notes', 'mark_fields_as_required_dynamically', 10, 1 ); /** * Validation for the Phone or Company fields when they have been set to required. */ function ts_field_validation() { if ( ! $_POST['billing_phone'] && 1 === (int) sanitize_text_field( wp_unslash( $_POST['ts_require_billing_phone'] ) ) ) { wc_add_notice( __( 'Billing Phone is a required field.', 'woocommerce' ), 'error' ); } if ( ! $_POST['billing_company'] && 1 === (int) sanitize_text_field( wp_unslash( $_POST['ts_require_billing_company'] ) ) ) { wc_add_notice( __( 'Billing Company is a required field.', 'woocommerce' ), 'error' ); } } add_action( 'woocommerce_checkout_process', 'ts_field_validation' );
As mentioned in the code snippet above, we start by adding fields which we want to be mandatory for all conditions in the function ts_require_fields_option(). The code inside this function will set the Phone & Company fields as required.
Now, if you want these fields to be optional for certain countries e.g. India and the US, or a combination of country + state e.g. India + Andhra Pradesh, you can mention the same in the ts_selected_country_state() function defined above, in an array:
return array( 'country' => array( 'IN', 'US' ), 'state' => array( 'AP' ), );
Here, the codes ‘IN’ and ‘US’ denote India and USA respectively, while ‘AP’ stands for Andhra Pradesh, a state in Southern India.
What this code will do is that, it will set the Phone and Company fields as mandatory, as we have assigned these fields ‘true’ values through the ts_require_fields_option() function above.
Only for USA and the state of Andhra Pradesh, these fields will be optional, as depicted below:
In this manner, you can bypass the “required” parameter for the fields that you want to set as optional, based on the countries or states selected.