在Woocommerce中将城市文本字段替换为特定国家/地区的城市下拉列表 [英] Replace the city text field by a dropdown of cities for a specific country in Woocommerce

查看:102
本文介绍了在Woocommerce中将城市文本字段替换为特定国家/地区的城市下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现有国家/地区列表非常好,但是我们需要特别选择沙特阿拉伯,并在其中显示其他列表,其中包含主要城市的名称,例如利雅得,吉达等.最后一个选项是另一个,如果他选择另一个,将出现一个文本框,写出它所在的城市或地区的名称.

The existing list of countries is excellent, but we need to select Saudi Arabia in particular and show it another list with the names of the main cities such as Riyadh, Jeddah, etc. The last option is another, and if he selects another, a text box will appear to write the name of the city or region in which it is located.

我试试这个,它和我一起工作的时候选择沙特,我可以显示城市的名单,但如果他选择其他我不能这样做,一个文本框会出现写的城市或地区的名字在其中位于.

I try this, Its work with me when select Saudi Arabia, i can show list of cities, but I could not do if he selects another, a text box will appear to write the name of the city or region in which it is located.

add_filter( 'woocommerce_default_address_fields' , 'customize_checkout_city_field' );
function customize_checkout_city_field( $address_fields ) {
global $woocommerce;
if ($woocommerce->customer->get_country() == 'SA') {    

                $towns_cities_arr = array(
            '0' => __('Select City', 'my_theme_slug'),
                    'Abhā' => 'Abhā',
                    'Abqaiq' => 'Abqaiq',
                    'Al-Baḥah' => 'Al-Baḥah',
                    'Al-Dammām' => 'Al-Dammām',
                    'Al-Hufūf' => 'Al-Hufūf',
                    'Al-Jawf' => 'Al-Jawf',
                    'Al-Kharj' => 'Al-Kharj',
                    'Al-Khubar' => 'Al-Khubar',
                    'Al-Qaṭīf' => 'Al-Qaṭīf',
                    'Al-Ṭaʾif' => 'Al-Ṭaʾif',
                    'ʿArʿar' => 'ʿArʿar',
                    'Buraydah' => 'Buraydah',
                    'Dhahran' => 'Dhahran',
                    'Ḥāʾil' => 'Ḥāʾil',
                    'Jiddah' => 'Jiddah',
                    'Jīzān' => 'Jīzān',
                    'Khamīs Mushayt' => 'Khamīs Mushayt',
                    'King Khalīd Military City' => 'King Khalīd Military City',
                    'Mecca' => 'Mecca',
                    'Medina' => 'Medina',
                    'Najrān' => 'Najrān',
                    'Ras Tanura' => 'Ras Tanura',
                    'Riyadh' => 'Riyadh',
                    'Sakākā' => 'Sakākā',
                    'Tabūk' => 'Tabūk',
                    'Yanbuʿ' => 'Yanbuʿ',
                    'Other' => 'Other',
                );
                $address_fields['city']['type'] = 'select';
                $address_fields['city']['class'] = array('update_totals_on_change');

                $address_fields['city']['label'] = __('City', 'my_theme_slug'); 

                $address_fields['city']['options'] = $towns_cities_arr;
} else {
                $address_fields['city']['type'] = 'text';
}   
                return $address_fields;         
}

推荐答案

已更新 (当从下拉菜单中选择其他"作为其他值时的附加城市文本字段)

以下代码(由 jQuery 提供支持)会将城市文本字段替换为城市的自定义下拉列表(仅适用于特定国家/地区)这个特定国家/地区,如果城市选择的值为其他",则其他文本字段将出现在城市下拉菜单中,客户可以在其中手动输入其他城市.

The following code (jQuery powered) will replace the city text field by a custom dropdown of cities for a specific country only and for this specific country, if the city selected value is "Others", an additional text field will appear under the cities dropdown, where customer can enter manually a different city.

该代码可独立用于运输和计费领域.

The code works for shipping and billing fields independently.

为定义的国家/地区选择其他"时,最后两个功能将:

When "Others" is selected for the defined country, the two last functions will:

  • 验证是否已填写城市附加字段
  • 将城市价值保存为开票或运输城市价值.

代码:

// HERE are is the array of cities for Saudi Arabia (SA)
function get_cities_options(){
    $domain = 'woocommerce'; // The domain text slug

    return array(
        ''          => __('Select a city', $domain),
        'Abhā'      => 'Abhā',      'Abqaiq'    => 'Abqaiq',
        'Al-Baḥah'  => 'Al-Baḥah',  'Al-Dammām' => 'Al-Dammām',
        'Al-Hufūf'  => 'Al-Hufūf',  'Al-Jawf'   => 'Al-Jawf',
        'Al-Kharj'  => 'Al-Kharj',  'Al-Khubar' => 'Al-Khubar',
        'Al-Qaṭīf'  => 'Al-Qaṭīf',  'Al-Ṭaʾif'  => 'Al-Ṭaʾif',
        'ʿArʿar'    => 'ʿArʿar',    'Buraydah'  => 'Buraydah',
        'Dhahran'   => 'Dhahran',   'Ḥāʾil'     => 'Ḥāʾil',
        'Jiddah'    => 'Jiddah','Jīzān'     => 'Jīzān',
        'Khamīs Mushayt'            => 'Khamīs Mushayt',
        'King Khalīd Military City' => 'King Khalīd Military City',
        'Mecca'     => 'Mecca',     'Medina'    => 'Medina',
        'Najrān'    => 'Najrān',    'Ras Tanura'=> 'Ras Tanura',
        'Riyadh'    => 'Riyadh',    'Sakākā'    => 'Sakākā',
        'Tabūk'     => 'Tabūk',     'Yanbuʿ'    => 'Yanbuʿ',
        'Other'     => __('Other cities (not listed)', $domain),
    );
}

// add an additional field
add_filter( 'woocommerce_checkout_fields' , 'additional_checkout_city_field' );
function additional_checkout_city_field( $fields ) {
    // Inline CSS To hide the fields on start
    ?><style> #billing_city2_field.hidden, #shipping_city2_field.hidden {display:none;}</style><?php

    $fields['billing']['billing_city2'] = array(
        'placeholder'   => _x('Other city', 'placeholder', 'woocommerce'),
        'required'  => false,
        'priority'  => 75,
        'class'     => array('form-row-wide hidden'),
        'clear'     => true
    );

    $fields['shipping']['shipping_city2'] = array(
        'placeholder'   => _x('Other city', 'placeholder', 'woocommerce'),
        'required'  => false,
        'priority'  => 75,
        'class'     => array('form-row-wide hidden'),
        'clear'     => true
    );

    return $fields;
}

// Add checkout custom select fields
add_action( 'wp_footer', 'custom_checkout_city_field', 20, 1 );
function custom_checkout_city_field() {
    // Only checkout page
    if( is_checkout() && ! is_wc_endpoint_url() ):

    $country = 'SA'; //  <=== <=== The country code

    $b_city  = 'billing_city';
    $s_city  = 'shipping_city';
    $billing_city_compo    = 'name="'.$b_city.'" id="'.$b_city.'"';
    $shipping_city_compo   = 'name="'.$s_city.'" id="'.$s_city.'"';
    $end_of_field          = ' autocomplete="address-level2" value="">';
    $billing_text_field    = '<input type="text" class="input-text" ' . $billing_city_compo  . $end_of_field;
    $shipping_text_field   = '<input type="text" class="input-text" ' . $shipping_city_compo . $end_of_field;
    $billing_select_field  = '<select ' . $billing_city_compo  . $end_of_field;
    $shipping_select_field = '<select ' . $shipping_city_compo . $end_of_field;

    ?>
    <script type="text/javascript">
    jQuery(function($){
        var a   = <?php echo json_encode( get_cities_options() ); ?>,           fc = 'form.checkout',
            b   = 'billing',                s   = 'shipping',               ci = '_city2',
            bc  = '<?php echo $b_city; ?>', sc = '<?php echo $s_city; ?>',  co = '_country',
            bci = '#'+bc,                   sci = '#'+sc,                   fi = '_field',
            btf = '<?php echo $billing_text_field; ?>',     stf = '<?php echo $shipping_text_field; ?>',
            bsf = '<?php echo $billing_select_field; ?>',   ssf = '<?php echo $shipping_select_field; ?>',
            cc  = '<?php echo $country; ?>';

        // Utility function that fill dynamically the select field options
        function dynamicSelectOptions( type ){
            var select = (type == b) ? bsf : ssf,
                fvalue = (type == b) ? $(bci).val() : $(sci).val();


            $.each( a, function( key, value ){
                selected = ( fvalue == key ) ? ' selected' : '';
                selected = ( ( fvalue == '' || fvalue == undefined ) && key == '' ) ? ' selected' : selected;
                select += '<option value="'+key+'"'+selected+'>'+value+'</option>';
            });
            select += '</select>';

            if ( type == b ) 
                $(bci).replaceWith(select);
            else 
                $(sci).replaceWith(select);
        }

        // Utility function that will show / hide the "country2" additional text field
        function showHideCity2( type, city ){
            var field   = (type == b) ? bci : sci,
                country = $('#'+type+co).val();

            if( country == cc && city == 'Other' && $('#'+type+ci+fi).hasClass('hidden') ){
                $('#'+type+ci+fi).removeClass('hidden');
            } else if( country != cc || ( city != 'Other' && ! $('#'+type+ci+fi).hasClass('hidden') ) ) {
                $('#'+type+ci+fi).addClass('hidden');
                if( country != cc && city == 'Other' ){
                    $(field).val('');
                }
            }
        }

        // On billing country change
        $(fc).on('change', '#'+b+co, function(){
            var bcv = $(bci).val();
            if($(this).val() == cc){
                if( $(bci).attr('type') == 'text' ){
                    dynamicSelectOptions(b);
                    showHideCity2( b, $(bci).val() );
                }
            } else {
                if( $(bci).attr('type') != 'text' ){
                    $(bci).replaceWith(btf);
                    $(bci).val(bcv);
                    showHideCity2( b, $(bci).val() );
                }
            }
        });

        // On shipping country change
        $(fc).on('change', '#'+s+co, function(){
            var scv = $(sc).val();
            if($(this).val() == cc){
                if( $(sci).attr('type') == 'text' ){
                    dynamicSelectOptions(s);
                    showHideCity2( s, $(sci).val() );
                }
            } else {
                if( $(sci).attr('type') != 'text' ){
                    $(sci).replaceWith(stf);
                    $(sci).val(scv);
                    showHideCity2( s, $(sci).val() );
                }
            }
        });

        // On billing city change
        $(fc).on('change', bci, function(){
            showHideCity2( b, $(this).val() );
        });

        // On shipping city change
        $(fc).on('change', sci, function(){
            showHideCity2( s, $(this).val() );
        });
    });
    </script>
    <?php
    endif;
}

// Check  for city 2 fields if billing or/and shipping city fields is "Other"
add_action('woocommerce_checkout_process', 'cbi_cf_process');
function cbi_cf_process() {
    // Check billing city 2 field
    if( isset($_POST['billing_city2']) && empty($_POST['billing_city2']) && $_POST['billing_city'] == 'Other' ){
        wc_add_notice( __( "Please fill in billing city field" ), "error" );
    }

    // Updating shipping city 2 field
    if( isset($_POST['shipping_city2']) && empty($_POST['shipping_city2']) && $_POST['shipping_city'] == 'Other' ){
        wc_add_notice( __( "Please fill in shipping city field" ), "error" );
    }
}

// Updating billing and shipping city fields when using "Other"
add_action( 'woocommerce_checkout_create_order', 'update_order_city_field', 30, 2 );
function update_order_city_field( $order, $posted_data ) {
    // Updating billing city from 'billing_city2'
    if( isset($_POST['billing_city2']) && ! empty($_POST['billing_city2']) && $_POST['billing_city'] == 'Other' ){
        $order->set_billing_city(sanitize_text_field( $_POST['billing_city2'] ) );
    }

    // Updating shipping city
    if( isset($_POST['shipping_city2']) && ! empty($_POST['shipping_city2']) && $_POST['shipping_city'] == 'Other' ){
        $order->set_shipping_city(sanitize_text_field( $_POST['shipping_city'] ) );
    }
}

代码进入您的活动子主题(活动主题)的function.php文件中.经过测试,可以正常工作.

Code goes in function.php file of your active child theme (active theme). Tested and works.

请记住,客户可以在Soudi阿拉伯(计费国家)以外的其他国家/地区购买要运往Soudi阿拉伯(运输国家)的东西.

Please Remember that a customer can be in a foreign country outside Soudi Arabia (billing country) and buy something that will be shipped in Soudi Arabia (shipping country).

这篇关于在Woocommerce中将城市文本字段替换为特定国家/地区的城市下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆