Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Created May 26, 2023 15:09
Show Gist options
  • Save igorbenic/277cf5095e77d00e30101d5768b9884e to your computer and use it in GitHub Desktop.
Save igorbenic/277cf5095e77d00e30101d5768b9884e to your computer and use it in GitHub Desktop.
How to add a City Dropdown to WooCommerce Checkout
jQuery( function( $ ) {
var cities = wc_city_dropdown.cities;
wrapper_selectors = '.woocommerce-billing-fields,' +
'.woocommerce-shipping-fields,' +
'.woocommerce-address-fields';
$( document.body ).on( 'change refresh', 'select.country_to_state, input.country_to_state', function() {
var $wrapper = $( this ).closest( wrapper_selectors );
if ( ! $wrapper.length ) {
$wrapper = $( this ).closest('.form-row').parent();
}
var country = $( this ).val(),
$citybox = $wrapper.find( '#billing_city, #shipping_city' ),
$parent = $citybox.closest( '.form-row' ),
input_name = $citybox.attr( 'name' ),
input_id = $citybox.attr('id'),
input_classes = $citybox.attr('data-input-classes'),
value = $citybox.val(),
placeholder = $citybox.attr( 'placeholder' ) || $citybox.attr( 'data-placeholder' ) || '',
$newcity;
// next code here
});
})
jQuery( function( $ ) {
var cities = wc_city_dropdown.cities;
wrapper_selectors = '.woocommerce-billing-fields,' +
'.woocommerce-shipping-fields,' +
'.woocommerce-address-fields';
$( document.body ).on( 'change refresh', 'select.country_to_state, input.country_to_state', function() {
// ... previous code
// If we have cities for a country, let's create a dropdown
// In case we have a country defined here, but no cities at all, we'll add a hidden field.
if ( cities[ country ] ) {
if ( $.isEmptyObject( cities[ country ] ) ) {
$newcity = $( '<input type="hidden" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.prop( 'placeholder', placeholder )
.attr( 'data-input-classes', input_classes )
.addClass( 'hidden ' + input_classes );
$parent.hide().find( '.select2-container' ).remove();
$citybox.replaceWith( $newcity );
$( document.body ).trigger( 'country_to_city_changed', [ country, $wrapper ] );
} else {
var city = cities[country],
$defaultOption = $('<option value=""></option>').text('Select a City');
if (!placeholder) {
placeholder = 'Select a City';
}
$parent.show();
if ($citybox.is('input')) {
$newcity = $('<select></select>')
.prop('id', input_id)
.prop('name', input_name)
.data('placeholder', placeholder)
.attr('data-input-classes', input_classes)
.addClass('state_select ' + input_classes);
$citybox.replaceWith($newcity);
$citybox = $wrapper.find('#billing_city, #shipping_city');
}
$citybox.empty().append($defaultOption);
$.each(city, function (index) {
var $option = $('<option></option>')
.prop('value', index)
.text(city[index]);
$citybox.append($option);
});
$citybox.val(value).trigger('change');
$( document.body ).trigger( 'country_to_city_changed', [country, $wrapper ] );
}
} else {
// No cities found and no country found? Create a regular text input field.
if ( $citybox.is( 'select, input[type="hidden"]' ) ) {
$newcity = $( '<input type="text" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.prop('placeholder', placeholder)
.attr('data-input-classes', input_classes )
.addClass( 'input-text ' + input_classes );
$parent.show().find( '.select2-container' ).remove();
$citybox.replaceWith( $newcity );
$( document.body ).trigger( 'country_to_city_changed', [country, $wrapper ] );
}
}
$( document.body ).trigger( 'country_to_city_changing', [country, $wrapper ] );
});
})
jQuery( function( $ ) {
var cities = wc_city_dropdown.cities;
wrapper_selectors = '.woocommerce-billing-fields,' +
'.woocommerce-shipping-fields,' +
'.woocommerce-address-fields';
$( document.body ).on( 'change refresh', 'select.country_to_state, input.country_to_state', function() {
var $wrapper = $( this ).closest( wrapper_selectors );
if ( ! $wrapper.length ) {
$wrapper = $( this ).closest('.form-row').parent();
}
var country = $( this ).val(),
$citybox = $wrapper.find( '#billing_city, #shipping_city' ),
$parent = $citybox.closest( '.form-row' ),
input_name = $citybox.attr( 'name' ),
input_id = $citybox.attr('id'),
input_classes = $citybox.attr('data-input-classes'),
value = $citybox.val(),
placeholder = $citybox.attr( 'placeholder' ) || $citybox.attr( 'data-placeholder' ) || '',
$newcity;
if ( cities[ country ] ) {
if ( $.isEmptyObject( cities[ country ] ) ) {
$newcity = $( '<input type="hidden" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.prop( 'placeholder', placeholder )
.attr( 'data-input-classes', input_classes )
.addClass( 'hidden ' + input_classes );
$parent.hide().find( '.select2-container' ).remove();
$citybox.replaceWith( $newcity );
$( document.body ).trigger( 'country_to_city_changed', [ country, $wrapper ] );
} else {
var city = cities[country],
$defaultOption = $('<option value=""></option>').text('Select a City');
if (!placeholder) {
placeholder = 'Select a City';
}
$parent.show();
if ($citybox.is('input')) {
$newcity = $('<select></select>')
.prop('id', input_id)
.prop('name', input_name)
.data('placeholder', placeholder)
.attr('data-input-classes', input_classes)
.addClass('state_select ' + input_classes);
$citybox.replaceWith($newcity);
$citybox = $wrapper.find('#billing_city, #shipping_city');
}
$citybox.empty().append($defaultOption);
$.each(city, function (index) {
var $option = $('<option></option>')
.prop('value', index)
.text(city[index]);
$citybox.append($option);
});
$citybox.val(value).trigger('change');
$( document.body ).trigger( 'country_to_city_changed', [country, $wrapper ] );
}
} else {
if ( $citybox.is( 'select, input[type="hidden"]' ) ) {
$newcity = $( '<input type="text" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.prop('placeholder', placeholder)
.attr('data-input-classes', input_classes )
.addClass( 'input-text ' + input_classes );
$parent.show().find( '.select2-container' ).remove();
$citybox.replaceWith( $newcity );
$( document.body ).trigger( 'country_to_city_changed', [country, $wrapper ] );
}
}
$( document.body ).trigger( 'country_to_city_changing', [country, $wrapper ] );
});
})
function myplugin_enqueue() {
if ( ! function_exists( 'is_checkout' ) ) {
return;
}
if ( ! is_checkout() ) {
return;
}
wp_enqueue_script(
'wc-city-dropdown',
trailingslashit( plugin_dir_url( __FILE__ ) ) . 'assets/checkout.js',
[ 'jquery' ],
filemtime( trailingslashit( plugin_dir_path( __FILE__ ) ) . 'assets/checkout.js' ),
true
);
wp_localize_script( 'wc-city-dropdown', 'wc_city_dropdown', [
'cities' => myplugin_get_cities()
]);
}
function myplugin_get_cities() {
$cities = [
'US' => [
'New York' => 'New York',
'Texas' => 'Texas',
],
'IT' => [
'Rome' => 'Rome',
'Venezia' => 'Venezia',
]
];
return $cities;
}
@hAbd0u
Copy link

hAbd0u commented Oct 3, 2024

Hello,
Thank you for this effort, can you put the instruction how to inject these codes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment