Hello guys how are you? Welcome back to my blog therichpost.com. Guys today in this post, I will tell you How to Implement Dynamic Town/City Dropdown in WooCommerce after selecting state/county or region?
Guys if you are new in WordPress or in WooCommerce then please check the below links for some good tutorials:
Guys here is the working steps and please follow carefully:
To implement a WooCommerce checkout page where the “Town/City” field is a dropdown that dynamically updates based on the selected “State/County” or “Region,” you’ll need to modify both the backend and frontend of your WordPress site.
Here’s how you can achieve this:
Steps to Implement Dynamic Town/City Dropdown in WooCommerce
1. Create a List of Towns/Cities for Each State/Region
You need a predefined list of towns/cities mapped to states/regions. Store this data in a format accessible to your script, such as a JSON file, a database table, or hardcoded in your theme’s PHP files.
Example JSON structure:
{
"US": {
"CA": ["Los Angeles", "San Francisco", "San Diego"],
"NY": ["New York City", "Buffalo", "Albany"]
},
"IN": {
"MH": ["Mumbai", "Pune", "Nagpur"],
"DL": ["New Delhi", "Dwarka", "Karol Bagh"]
}
}
2. Enqueue Custom JavaScript for Frontend Behavior
Add JavaScript to dynamically load towns/cities when a state/region is selected.
In your theme’s functions.php, enqueue the script:
function custom_checkout_scripts() {
wp_enqueue_script('custom-checkout', get_template_directory_uri() . '/js/custom-checkout.js', array('jquery'), '1.0', true);
wp_localize_script('custom-checkout', 'locationData', array(
'ajax_url' => admin_url('admin-ajax.php'),
'cities' => json_encode([
'US' => [
'CA' => ['Los Angeles', 'San Francisco', 'San Diego'],
'NY' => ['New York City', 'Buffalo', 'Albany']
],
'IN' => [
'MH' => ['Mumbai', 'Pune', 'Nagpur'],
'DL' => ['New Delhi', 'Dwarka', 'Karol Bagh']
]
])
));
}
add_action('wp_enqueue_scripts', 'custom_checkout_scripts');
3. Create the JavaScript File (custom-checkout.js)
Handle the dropdown behavior in JavaScript:
jQuery(document).ready(function ($) {
const cities = JSON.parse(locationData.cities);
$('#billing_state').on('change', function () {
const country = $('#billing_country').val();
const state = $(this).val();
if (cities[country] && cities[country][state]) {
const townDropdown = $('#billing_city');
townDropdown.empty();
townDropdown.append('<option value="">Select a city</option>');
cities[country][state].forEach(function (city) {
townDropdown.append(`<option value="${city}">${city}</option>`);
});
townDropdown.prop('disabled', false);
} else {
$('#billing_city').empty().append('<option value="">No cities available</option>').prop('disabled', true);
}
});
});
4. Modify Checkout Fields to Use Dropdown for Town/City
Use the woocommerce_checkout_fields filter to make the “Town/City” field a dropdown:
function custom_override_checkout_fields($fields) {
$fields['billing']['billing_city'] = array(
'type' => 'select',
'label' => __('Town/City'),
'required' => true,
'options' => array('' => 'Select a city'), // Placeholder, dynamically populated
'class' => array('form-row-wide'),
'priority' => 50,
);
return $fields;
}
add_filter('woocommerce_checkout_fields', 'custom_override_checkout_fields');
5. Optional: Use AJAX for Server-Side Data
If the list of towns/cities is large, you can use AJAX to fetch them dynamically instead of embedding them in the JavaScript.
PHP: Handle AJAX Request
function load_cities_ajax() {
$country = $_POST['country'];
$state = $_POST['state'];
$cities = [
'US' => [
'CA' => ['Los Angeles', 'San Francisco', 'San Diego'],
'NY' => ['New York City', 'Buffalo', 'Albany']
],
'IN' => [
'MH' => ['Mumbai', 'Pune', 'Nagpur'],
'DL' => ['New Delhi', 'Dwarka', 'Karol Bagh']
]
];
if (isset($cities[$country][$state])) {
wp_send_json($cities[$country][$state]);
} else {
wp_send_json([]);
}
wp_die();
}
add_action('wp_ajax_load_cities', 'load_cities_ajax');
add_action('wp_ajax_nopriv_load_cities', 'load_cities_ajax');
JavaScript: Fetch Cities via AJAX
Replace the local data handling with an AJAX call:
$('#billing_state').on('change', function () {
const country = $('#billing_country').val();
const state = $(this).val();
$.post(locationData.ajax_url, {
action: 'load_cities',
country: country,
state: state
}, function (response) {
const townDropdown = $('#billing_city');
townDropdown.empty();
if (response.length > 0) {
townDropdown.append('<option value="">Select a city</option>');
response.forEach(function (city) {
townDropdown.append(`<option value="${city}">${city}</option>`);
});
townDropdown.prop('disabled', false);
} else {
townDropdown.append('<option value="">No cities available</option>').prop('disabled', true);
}
});
});

6. Test and Debug
- Verify the dropdowns update dynamically as expected.
- Test with different countries/states.
- Ensure the fields are properly validated during checkout.
This approach ensures your checkout page is dynamic and user-friendly.
Guys if you will have any kind of query then feel free to comment below.
Thanks
Jassa