最近有蠻多客戶提出需要有縣市跟鄉鎮市自動下拉的功能,實作之後發現其實並沒有想像中的難,因此將作法分享給大家,基本上我們需要的功能是:
- 國家為台灣時,縣市需要產生自動下拉選項。
- 選擇縣市後,鄉鎮市需要自動根據選擇的縣市帶出鄉鎮市的下拉選單。
- 選擇鄉鎮市後,需要自動帶入郵遞區號。
直接購買外掛!
除了照著我們的做法加入程式之外,您也可以直接購買現成的外掛,縣市/鄉鎮市下拉選單外掛,省時又方便!
加入縣市下拉選項
這部分蠻簡單的,在主題的functions.php加上下面的程式碼,基本上這段程式就是將台灣的縣市清單加進去,這樣WooCommerce就會自動幫我們產生下拉了。
add_filter("woocommerce_states", 'add_taiwan_states', 10);
/**
* Add Taiwan States
* @param array $states
*/
function add_taiwan_states($states) {
$states['TW'] = array(
'基隆市' => '基隆市',
'台北市' => '台北市',
'新北市' => '新北市',
'宜蘭縣' => '宜蘭縣',
'桃園市' => '桃園市',
'新竹市' => '新竹市',
'新竹縣' => '新竹縣',
'苗栗縣' => '苗栗縣',
'台中市' => '台中市',
'彰化縣' => '彰化縣',
'南投縣' => '南投縣',
'雲林縣' => '雲林縣',
'嘉義市' => '嘉義市',
'嘉義縣' => '嘉義縣',
'台南市' => '台南市',
'高雄市' => '高雄市',
'屏東縣' => '屏東縣',
'花蓮縣' => '花蓮縣',
'台東縣' => '台東縣',
'澎湖縣' => '澎湖縣',
'連江縣' => '連江縣',
'金門縣' => '金門縣'
);
return $states;
}
}
加入javascript
因為WooCommerce並沒有直接的API讓我們加入鄉鎮市的下拉,所以我們需要自己加入javascript來製作,還好並不是非常困難,請在您的主題下新增一個checkout-dropdown.js,然後將下段程式碼加進去。
jQuery(function ($) {
if (!$('form.woocommerce-checkout')) {
return;
}
var cities = Inno_Object.cities;
var target_checkout_fields = [
{
state: '#billing_state',
city: '#billing_city',
postcode: '#billing_postcode'}
, {
state: '#shipping_state',
city: '#shipping_city',
postcode: '#shipping_postcode'
}
];
/**
* init all state fields, on state change, load city list
*/
target_checkout_fields.forEach(function (field) {
var state_field = field.state;
var city_field = field.city;
$(state_field).change(function () {
//get current city
var current_city = $(city_field).val();
var state = $(this).val();
var has_current_city = false;
//destroy select2 first
if ($(city_field).hasClass("select2-hidden-accessible")) {
$(city_field).select2('destroy');
}
if (state && cities[state]) {
var state_cities = cities[state];
var data = [];
state_cities.forEach(function (city) {
data.push({
id: city.suburb,
text: city.suburb
});
if (city.suburb == current_city) {
has_current_city = true;
}
});
$(city_field).select2({
data: data,
placeholder: "選擇鄉鎮市",
width:'100%'
});
}
if (!has_current_city) {
$(city_field).val('');
}
$(city_field).trigger('change');
});
$(state_field).trigger('change');
});
/**
* On city change, load post code automatically
*/
target_checkout_fields.forEach(function (field) {
var state_field = field.state;
var city_field = field.city;
var postcode_field = field.postcode;
$(city_field).change(function () {
//reset
var state = $(state_field).val();
var selected_city = $(this).val();
var reset_postcode = true;
if (state && cities[state]) {
var state_cities = cities[state];
state_cities.forEach(function (city) {
if (city.suburb == selected_city) {
$(postcode_field).val(city.postcode);
reset_postcode = false;
}
});
}
if (reset_postcode) {
$(postcode_field).val('');
}
});
$(city_field).trigger('change');
});
});
加入taiwan.xml
下載taiwan.xml並且放在您的主題裡,這個檔案包含了台灣的所有縣市,鄉鎮市以及郵遞區號的資料,我們需要這個檔案來找出對應的縣市鄉鎮市和郵遞區號。
請將下列程式碼加入functions.php中,這段程式是用來將xml的內容轉成javascript可讀的格式。
注意:請將程式碼中的plugin_dir_path(FILE) . ‘taiwan.xml’)改為正確的路徑。
/**
* Get city list from xml
* @return type
*/
function get_city_list() {
$city_list = array();
if (file_exists(plugin_dir_path(__FILE__) . 'taiwan.xml')) {
$xml = simplexml_load_file(plugin_dir_path(__FILE__) . 'taiwan.xml');
foreach ($xml->county as $county) {
$county_name = (string) $county->attributes()->name;
$city_list[$county_name] = array();
foreach ($county->area as $area) {
$str_area = (string) $area;
$str_postcode = (string) $area->attributes()->zip;
$city_list[$county_name][] = array('suburb' => $str_area, 'postcode' => $str_postcode);
}
}
}
return $city_list;
}
Enqueue JS以及鄉鎮市資料
我們需要在結帳頁面加入上面建立的checkout-dropdown.js以及提供鄉鎮市資料到前端,只要加上下面程式即可。
注意:請更改checkout-dropdown.js的路徑。
add_action('wp_enqueue_scripts', 'enqueue_tw_dropdown_scripts');
/**
* Enqueue Scripts
*/
function enqueue_tw_dropdown_scripts() {
if (is_checkout()) {
$script_data['cities'] = get_city_list();
wp_enqueue_script('checkout-city-dropdown', plugin_dir_url(__FILE__) . 'assets/js/checkout-dropdown.js', array('select2'), filemtime(plugin_dir_path(__FILE__) . 'assets/js/checkout-dropdown.js'), true);
wp_localize_script('checkout-city-dropdown', 'Inno_Object', $script_data);
}
}
大功告成!現在您的結帳頁面應該會有縣市以及鄉鎮市的下拉了!