php - 将城市文本字段替换为 Woocommerce 中特定国家/地区的城市下拉列表

标签 php jquery wordpress woocommerce checkout

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

我尝试这个,当选择沙特阿拉伯时,它对我有用,我可以显示城市列表,但如果他选择另一个,我就不能这样做,会出现一个文本框,写出它所在的城市或地区的名称位于。

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;         
}

最佳答案

Updated (Additional city text field when "Others" is the selected value from the dropdown)

以下代码(jQuery 驱动) 将用城市的自定义下拉列表替换城市文本字段仅适用于特定国家在此特定国家/地区,如果城市选择值为“其他”,城市下拉列表下将出现一个附加文本字段,客户可以在其中手动输入不同的城市。

该代码独立适用于运输和计费字段。

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

  • 验证城市附加字段是否已填写,
  • 将城市值保存为结算或送货城市值。

代码:

// 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 文件中。经过测试并有效。

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).

关于php - 将城市文本字段替换为 Woocommerce 中特定国家/地区的城市下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52605635/

相关文章:

javascript - 计算两个日期时间本地输入之间的小时数

php - 在 wordpress 中显示所有帖子的 url 是什么?

javascript - 嵌入代码不会显示在 WordPress 页面中

css - 更改位置 Product_Tittle Woocommerce

php - Mysql 没有保存带有 ' 字符的答案

php - 网站翻译器

javascript - 如何使用 jQuery 将 HTML 表格转换为 Javascript 对象

php - explode() 到 $key=>$value 对

php - 在 Drupal 7 中重新启用禁用完整 html

javascript - 如何将 Fullcalendar 插件中的日期与日期数组进行比较