W e b I n s i g h t s .

WooCommerce縣市/鄉鎮市下拉選單

WooCommerce縣市/鄉鎮市下拉選單

最近有蠻多客戶提出需要有縣市跟鄉鎮市自動下拉的功能,實作之後發現其實並沒有想像中的難,因此將作法分享給大家,基本上我們需要的功能是:

  1. 國家為台灣時,縣市需要產生自動下拉選項。
  2. 選擇縣市後,鄉鎮市需要自動根據選擇的縣市帶出鄉鎮市的下拉選單。
  3. 選擇鄉鎮市後,需要自動帶入郵遞區號。

直接購買外掛!

除了照著我們的做法加入程式之外,您也可以直接購買現成的外掛,縣市/鄉鎮市下拉選單外掛,省時又方便!

加入縣市下拉選項

這部分蠻簡單的,在主題的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);
                }
            }

大功告成!現在您的結帳頁面應該會有縣市以及鄉鎮市的下拉了!

 

文章最後更新於 : 2022/12/23