将 WooCommerce 结帐城市字段更改为一个独特国家的下拉列表
Change WooCommerce checkout city field to a dropdown for a unique country
在 Woocommerce 中,我编写了一些用于计费和送货城市的代码以使用运费。现在我想在更改国家/地区时更改城市列表。
这是我的自定义代码:
// Change "city" checkout billing and shipping fields to a dropdown
add_filter( 'woocommerce_checkout_fields' , 'override_checkout_city_fields' );
function override_checkout_city_fields( $fields ) {
global $woocommerce;
// Define here in the array your desired cities (Here an example of cities)
$option_cities = array(
"city1"=>"city1",
"city2"=>"city2",
"city3"=>"city3"
);
$country = $woocommerce->customer->get_shipping_country();
if ($country == 'SA'){
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = $option_cities;
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = $option_cities;
} else{
$fields['billing']['billing_city']['type'] = 'text';
$fields['shipping']['shipping_city']['type'] = 'text';
}
return $fields;
}
但是当用户将国家从沙特阿拉伯更改为卡塔尔时,billing_city
不会更改为文本类型,因此我们必须刷新页面以将billing_city
显示为文本类型。
我只需要 billing_city
作为“沙特阿拉伯”国家/地区的 select 类型。其他国家/地区我们需要显示文本类型。
我该怎么做?
这需要与 javascript 不同的东西,因为它基于客户端(浏览器端)事件。
因此您需要保持 WooCommerce 账单城市和发货城市字段不变,我们将在此处添加额外的自定义 select 字段(默认隐藏)。
然后当 selected 国家为“沙特阿拉伯”(您的目标国家)时,默认的 WooCommerce 城市字段将被隐藏,相关的自定义 select 字段将被显示。
当在城市下拉字段中 select 编辑一个值时,我们会将该值复制到 WooCommerce 默认城市输入字段(即使它是隐藏的)。
所以当客户下订单时,WooCommerce 无论如何都会有正确的城市价值。
Note that the billing address is different from shipping address and a customer can have a billing country different from the shipping country… So you need to take more care about billing and shipping addresses behaviors.
完整代码如下:
// Add custom checkout select fields
add_filter( 'woocommerce_checkout_fields', 'add_custom_checkout_select_fields' );
function add_custom_checkout_select_fields( $fields ) {
// Define HERE in the array, your desired cities
$cities = array(
__( 'City1', 'woocommerce' ),
__( 'City2', 'woocommerce' ),
__( 'City3', 'woocommerce' ),
);
// Format in the right way the options array of cities
$options = array( '' => __( 'Select a city', 'woocommerce' ) . '…' );
foreach ( $cities as $city ) {
$options[$city] = $city;
}
// Adding 2 custom select fields
$fields['billing']['billing_city2'] = $fields['shipping']['shipping_city2'] = array(
'type' => 'select',
'required' => true,
'options' => $options,
'autocomplete' => 'address-level2',
);
// Copying data from WooCommerce city fields
$fields['billing']['billing_city2']['class'] = array_merge($fields['billing']['billing_city']['class'], array('hidden') );
$fields['shipping']['shipping_city2']['class'] = array_merge($fields['shipping']['shipping_city']['class'], array('hidden') );
$fields['billing']['billing_city2']['label'] = $fields['billing']['billing_city']['label'];
$fields['shipping']['shipping_city2']['label'] = $fields['shipping']['shipping_city']['label'];
$fields['billing']['billing_city2']['priority'] = $fields['billing']['billing_city']['priority'] + 5;
$fields['shipping']['shipping_city2']['priority'] = $fields['shipping']['shipping_city']['priority'] + 5;
return $fields;
}
// Custom inline styles to hide some checkout fields
add_action( 'wp_head', 'custom_checkout_css' );
function custom_checkout_css() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) {
?><style>
#billing_city_field.hidden, #billing_city2_field.hidden,
#shipping_city_field.hidden, #shipping_city2_field.hidden
{display:none !important;}
</style><?php
}
}
// Custom jQuery code
add_action( 'wp_footer', 'custom_checkout_js_script' );
function custom_checkout_js_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
(function($){
var targetedCountry = 'FR',
initialBCountry = '<?php echo WC()->customer->get_billing_country(); ?>',
initialSCountry = '<?php echo WC()->customer->get_shipping_country(); ?>';
function showHideFields( country, fieldset ) {
var select2Classes = 'country_select select2-hidden-accessible';
if( country === targetedCountry ) {
$('#'+fieldset+'_city2_field').removeClass('hidden');
$('#'+fieldset+'_city_field').addClass('hidden');
$('select#'+fieldset+'_city2').addClass(select2Classes);
} else if( country !== targetedCountry && $('#'+fieldset+'_city_field').hasClass('hidden') ) {
$('#'+fieldset+'_city2_field').addClass('hidden');
$('#'+fieldset+'_city_field').removeClass('hidden');
$('select#'+fieldset+'_city2').removeClass(select2Classes);
}
}
// 1. On Start (after Checkout is loaded)
showHideFields(initialBCountry, 'billing');
showHideFields(initialSCountry, 'shipping');
// 2. Live: On Country change event
$('body').on( 'change', 'select#billing_country', function(){
showHideFields($(this).val(), 'billing');
});
$('body').on( 'change', 'select#shipping_country', function(){
showHideFields($(this).val(), 'shipping');
});
// 3. Live: On City change event for "Saudi Arabia" country
$('body').on( 'change', 'select#billing_city2', function(){
$('input#billing_city').val($(this).val());
});
$('body').on( 'change', 'select#shipping_city2', function(){
$('input#shipping_city').val($(this).val());
});
})(jQuery);
</script>
<?php
endif;
}
代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。
在 Woocommerce 中,我编写了一些用于计费和送货城市的代码以使用运费。现在我想在更改国家/地区时更改城市列表。
这是我的自定义代码:
// Change "city" checkout billing and shipping fields to a dropdown
add_filter( 'woocommerce_checkout_fields' , 'override_checkout_city_fields' );
function override_checkout_city_fields( $fields ) {
global $woocommerce;
// Define here in the array your desired cities (Here an example of cities)
$option_cities = array(
"city1"=>"city1",
"city2"=>"city2",
"city3"=>"city3"
);
$country = $woocommerce->customer->get_shipping_country();
if ($country == 'SA'){
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = $option_cities;
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = $option_cities;
} else{
$fields['billing']['billing_city']['type'] = 'text';
$fields['shipping']['shipping_city']['type'] = 'text';
}
return $fields;
}
但是当用户将国家从沙特阿拉伯更改为卡塔尔时,billing_city
不会更改为文本类型,因此我们必须刷新页面以将billing_city
显示为文本类型。
我只需要 billing_city
作为“沙特阿拉伯”国家/地区的 select 类型。其他国家/地区我们需要显示文本类型。
我该怎么做?
这需要与 javascript 不同的东西,因为它基于客户端(浏览器端)事件。
因此您需要保持 WooCommerce 账单城市和发货城市字段不变,我们将在此处添加额外的自定义 select 字段(默认隐藏)。
然后当 selected 国家为“沙特阿拉伯”(您的目标国家)时,默认的 WooCommerce 城市字段将被隐藏,相关的自定义 select 字段将被显示。
当在城市下拉字段中 select 编辑一个值时,我们会将该值复制到 WooCommerce 默认城市输入字段(即使它是隐藏的)。
所以当客户下订单时,WooCommerce 无论如何都会有正确的城市价值。
Note that the billing address is different from shipping address and a customer can have a billing country different from the shipping country… So you need to take more care about billing and shipping addresses behaviors.
完整代码如下:
// Add custom checkout select fields
add_filter( 'woocommerce_checkout_fields', 'add_custom_checkout_select_fields' );
function add_custom_checkout_select_fields( $fields ) {
// Define HERE in the array, your desired cities
$cities = array(
__( 'City1', 'woocommerce' ),
__( 'City2', 'woocommerce' ),
__( 'City3', 'woocommerce' ),
);
// Format in the right way the options array of cities
$options = array( '' => __( 'Select a city', 'woocommerce' ) . '…' );
foreach ( $cities as $city ) {
$options[$city] = $city;
}
// Adding 2 custom select fields
$fields['billing']['billing_city2'] = $fields['shipping']['shipping_city2'] = array(
'type' => 'select',
'required' => true,
'options' => $options,
'autocomplete' => 'address-level2',
);
// Copying data from WooCommerce city fields
$fields['billing']['billing_city2']['class'] = array_merge($fields['billing']['billing_city']['class'], array('hidden') );
$fields['shipping']['shipping_city2']['class'] = array_merge($fields['shipping']['shipping_city']['class'], array('hidden') );
$fields['billing']['billing_city2']['label'] = $fields['billing']['billing_city']['label'];
$fields['shipping']['shipping_city2']['label'] = $fields['shipping']['shipping_city']['label'];
$fields['billing']['billing_city2']['priority'] = $fields['billing']['billing_city']['priority'] + 5;
$fields['shipping']['shipping_city2']['priority'] = $fields['shipping']['shipping_city']['priority'] + 5;
return $fields;
}
// Custom inline styles to hide some checkout fields
add_action( 'wp_head', 'custom_checkout_css' );
function custom_checkout_css() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) {
?><style>
#billing_city_field.hidden, #billing_city2_field.hidden,
#shipping_city_field.hidden, #shipping_city2_field.hidden
{display:none !important;}
</style><?php
}
}
// Custom jQuery code
add_action( 'wp_footer', 'custom_checkout_js_script' );
function custom_checkout_js_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
(function($){
var targetedCountry = 'FR',
initialBCountry = '<?php echo WC()->customer->get_billing_country(); ?>',
initialSCountry = '<?php echo WC()->customer->get_shipping_country(); ?>';
function showHideFields( country, fieldset ) {
var select2Classes = 'country_select select2-hidden-accessible';
if( country === targetedCountry ) {
$('#'+fieldset+'_city2_field').removeClass('hidden');
$('#'+fieldset+'_city_field').addClass('hidden');
$('select#'+fieldset+'_city2').addClass(select2Classes);
} else if( country !== targetedCountry && $('#'+fieldset+'_city_field').hasClass('hidden') ) {
$('#'+fieldset+'_city2_field').addClass('hidden');
$('#'+fieldset+'_city_field').removeClass('hidden');
$('select#'+fieldset+'_city2').removeClass(select2Classes);
}
}
// 1. On Start (after Checkout is loaded)
showHideFields(initialBCountry, 'billing');
showHideFields(initialSCountry, 'shipping');
// 2. Live: On Country change event
$('body').on( 'change', 'select#billing_country', function(){
showHideFields($(this).val(), 'billing');
});
$('body').on( 'change', 'select#shipping_country', function(){
showHideFields($(this).val(), 'shipping');
});
// 3. Live: On City change event for "Saudi Arabia" country
$('body').on( 'change', 'select#billing_city2', function(){
$('input#billing_city').val($(this).val());
});
$('body').on( 'change', 'select#shipping_city2', function(){
$('input#shipping_city').val($(this).val());
});
})(jQuery);
</script>
<?php
endif;
}
代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。