phpwoocommercelocalecheckoutaccount

Change Checkout and My Account address fields settings by country in Woocommerce


I'm using this code to change some checkout address fields to reflect more correct address formats in some countries. Other countries fields work but UK and New Zealand state label changing part does not work. UK's County (optional) field still has the same label and New Zealand's Region (optional) field is still a dropdown list with the same label. I have a feeling that there might be WC core's javascript overriding something here. Any ideas?

function modify_default_address_fields($address_fields) {
    if ( function_exists('WC') && WC()->customer && ( is_checkout() || is_account_page() ) ) {
        $country = WC()->customer->get_billing_country();

        // Taiwan
        if ($country === 'TW') {
            $address_fields['city']['label'] = 'District';
            $address_fields['state']['label'] = 'City';
        }

        // Hong Kong
        if ($country === 'HK') {
            $address_fields['address_1']['label'] = 'Flat/Unit, Floor, Building, Street';
            $address_fields['city']['label'] = 'District';
            unset($address_fields['postcode']);
        }

        // Germany
        if ($country === 'DE') {
            unset($address_fields['state']);
        }
        
        // UK
        if ($country === 'GB') {
            $address_fields['city']['label'] = 'Locality / Village name (optional)';
            $address_fields['state']['required'] = true;
            $address_fields['state']['label'] = 'Town / City';
        }

        // New Zealand
        if ($country === 'NZ') {
            $address_fields['city']['label'] = 'Suburb';
            $address_fields['state']['required'] = true;
            $address_fields['state']['label'] = 'Town / City';
            $address_fields['state']['type'] = 'text';
        }

    }
    return $address_fields;
}
// Make sure all systems are loaded before executing the function (prevent fatal error)
function initialize_address_field_modifications() {
    add_filter('woocommerce_default_address_fields', 'modify_default_address_fields', 9999);
}
add_action('init', 'initialize_address_field_modifications');

Solution

  • You are not using the right hook, for that. Try instead the following instead:

    add_filter('woocommerce_get_country_locale', 'alter_addresses_fields_based_on_country',);
    function alter_addresses_fields_based_on_country($locale) {
        $hide_field = array('required' => false, 'hidden' => true );
    
        // Taiwan
        $locale['TW']['city']['label']  = __('District', 'woocommerce');
        $locale['TW']['state']['label'] = __('City', 'woocommerce');
    
        // Hong Kong
        $locale['HK']['address_1']['label'] = __('Flat/Unit, Floor, Building, Street', 'woocommerce');
        $locale['HK']['city']['label']      = __('District', 'woocommerce');
        $locale['HK']['postcode']           = $hide_field;
    
        // Germany
        $locale['DE']['state'] = $hide_field;
    
        // United Kingdom 
        $locale['GB']['city'] = array( 
            'required'  => false, 
            'label'     => __('Locality / Village name', 'woocommerce')
        );
        $locale['GB']['state'] = array(
            'required'  => true, 
            'label'     => __('Town / City', 'woocommerce')
        );
    
        // New Zealand
        $locale['NZ']['city']['label'] = __('Suburb', 'woocommerce');
        $locale['NZ']['state'] = array(
            'required'  => true,
            'label'     =>  __('Town / City', 'woocommerce'),
            'type'      =>  __('text', 'woocommerce'),
        );
    
        return $locale;
    }
    

    Code goes in functions.php file of your active child theme (or in a plugin). Tested and work.

    Related: See WC_Countries get_country_locale() method, using an array of specific fields setting rules by country.