不同的城市选择字段取决于 WooCommerce 中的所选国家/地区

Different City select field depending on selected country in WooCommerce

提问人:libertarian 提问时间:11/17/2023 最后编辑:LoicTheAzteclibertarian 更新时间:11/18/2023 访问量:67

问:

在结帐时,我为几个国家/地区进行了单独的城市选择(它们的值将转到隐藏的默认文本字段billing_address_1)。曼城选择我自己做的,他们是个人的。

我还使用流行的解决方案来使用 ajax 更新所有字段。 更改时一切正常 - 当我更改国家/地区时,所有国家/地区选择都是隐藏的,并且所选国家/地区的一个城市选择是可见的,但它在屏幕加载时不起作用。 我只会在 2 个国家/地区显示,但还有更多,代码对其他国家/地区相同 - 只是要隐藏更多字段。

add_action("wp_footer", "add_script_update_shipping_method");
function add_script_update_shipping_method()
{
    if (is_checkout()) { ?>

    <script>
    jQuery(document).ready(function($) {
        jQuery('select#billing_city_ua,select#billing_city_pl').select2();

        /* DIDN'T HELP

         jQuery(window).on('load', function () { 
         var countryval =  jQuery('#billing_country option:selected').val();                    
               jQuery('#billing_country').val(countryval);      
       });

        TO COPY ALL STRINGS FROM CHANGE TOO
       */

        $(document.body).on('updated_checkout updated_shipping_method', function(event, xhr, data) {

            $('input[name^="shipping_method"]').on('change', function() {
                $('.woocommerce-billing-fields__field-wrapper').block({
                    message: null,
                    overlayCSS: {
                        background: '#fff',
                        'z-index': 1000000,
                        opacity: 0.3
                    }
                });
            });


            jQuery('select#billing_country').on('change', function() {
                jQuery('select#billing_city_ua, select#billing_city_pl, p#billing_city_field input').val('');
                if (jQuery(this).val() == "UA") {
                    jQuery('select#billing_city_pl').addClass('d-none').removeClass('d-flex').closest('p').hide();
                    jQuery('select#billing_city_ua').addClass('d-flex').removeClass('d-none').closest('p').show();
                }
                if (jQuery(this).val() == "PL") {
                    jQuery('select#billing_city_ua').addClass('d-none').removeClass('d-flex').closest('p').hide();
                    jQuery('select#billing_city_pl').addClass('d-flex').removeClass('d-none').closest('p').show();
                }

            });


            jQuery("select#billing_city_ua").on("change", function(e) {
                let cityval = jQuery("select#billing_city_ua").val();
                jQuery(this).find('.woocommerce-billing-fields__field-wrapper p#billing_city_field>span>input').val(cityval);
            });
            jQuery("select#billing_city_pl").on("change", function(e) {
                let cityval = jQuery("select#billing_city_pl").val();
                jQuery(this).find('.woocommerce-billing-fields__field-wrapper p#billing_city_field>span>input').val(cityval);
            });



            var first_name = $('#billing_first_name').val(),
                last_name = $('#billing_last_name').val(),
                phone = $('#billing_phone').val(),
                email = $('#billing_email').val(),
                city = $('#billing_city').val(),
                cityua = $('#billing_city_ua').val(),
                citypl = $('#billing_city_pl').val(),
                address = $('#billing_address_1').val(),
                postcode = $('#billing_postcode').val(),
                country = $('#billing_country').val();

            $(".woocommerce-billing-fields__field-wrapper").html(xhr.fragments[".woocommerce-billing-fields"]);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_first_name"]').val(first_name);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_last_name"]').val(last_name);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_phone"]').val(phone);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_email"]').val(email);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_city"]').val(city);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_city_ua"]').val(cityua);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_city_pl"]').val(citypl);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_postcode"]').val(postcode);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_country"]').val(country);
            $(".woocommerce-billing-fields__field-wrapper").find('input[name="billing_address_1"]').val(address);
            $('.woocommerce-billing-fields__field-wrapper').unblock();
        });
    });
    </script>
    <?php }
}

我尝试了很多技巧 - 在身体变化时触发变化事件,甚至在悬停或滚动时只是为了测试。所有国家/地区选择在页面加载时都可见,当您选择国家/地区时,一切正常。我想在加载时重新选择已选择的值 - 也使用 cityval。要从头开始复制所有代码,请在 xhr 函数无济于事之前更改代码。正确的方法是什么?

已编辑 - 添加了代码 如何添加城市选择字段

add_filter( 'woocommerce_checkout_fields' , 'dropdown' );

// Our hooked in function - $fields is passed via the filter!
function dropdown( $fields ) {
     $fields['billing']['billing_city_ua'] = array(
    'label'     => __('City', 'woocommerce'),
    'placeholder'   => _x('billing_city_ua', 'Select your city', 'woocommerce'),
    'required'  => false,
    'class'     => array('form-row-wide cities-select'),
    'clear'     => true,
    'type'      => 'select',
  'priority'   => 88,
     'options'     => array(
         '' => __('Select city', 'woocommerce' ),
        'City1' => __('City1', 'woocommerce' ),
        'City2' => __('City2', 'woocommerce' ),
        'City3' => __('City3', 'woocommerce' ),
        'City4' => __('City4', 'woocommerce' ),
        )
     ); 

   $fields['billing']['billing_city_pl'] = array(
    'label'     => __('City', 'woocommerce'),
    'placeholder'   => _x('billing_city_pl', 'Select your city', 'woocommerce'),
    'required'  => false,
    'class'     => array('form-row-wide cities-select'),
    'clear'     => true,
    'type'      => 'select',
  'priority'   => 88, 
        'options'     => array(
         '' => __('Select city', 'woocommerce' ),
        'City1' => __('City1', 'woocommerce' ),
        'City2' => __('City2', 'woocommerce' ),
        'City3' => __('City3', 'woocommerce' ),
        'City4' => __('City4', 'woocommerce' ),
        )
     );    


     return $fields;
}
php jquery woocommerce html-select 结帐

评论

0赞 libertarian 11/17/2023
我补充说,我认为这就是可以与字段连接的全部内容,没有插件
0赞 libertarian 11/17/2023
d-none、d-flex 我认为可以理解,带有父级“p”的可见块,当选择是或隐藏时
0赞 libertarian 11/17/2023
其他国家/地区喜欢 if (jQuery(this).val() == “UA”) { jQuery('select#billing_city_pl,select#billing_city_xx,select#billing_city_xy,select#billing_city_yy').addClass('d-none').removeClass('d-flex').closest('p').hide(); jQuery('select#billing_city_ua').addClass('d-flex').removeClass('d-none').closest('p').show();目前,默认城市字段尚未隐藏,但会隐藏。是的,现在它是从选定的城市中填充的,这些城市必须根据所选国家/地区显示。国家/地区选择默认为 wc-“在 5 个国家/地区销售”选项。
0赞 libertarian 11/17/2023
通过 css 还没有隐藏任何东西,只有我展示的脚本 - d-none、d-flex。我只想显示一个城市选择 - 取决于国家/地区。如果这是客户的第一次访问 - 这是一个默认值,用于显示其城市。如果客户选择某样东西,它必须是选择的国家和它的城市选择,所有城市选择都是分开的,

答:

1赞 LoicTheAztec 11/17/2023 #1

我已经完全重新审视了你的JavaScript代码,并添加了一些缺失的东西。

将所有相关代码替换为以下内容:

// Add custom city select fields
add_filter( 'woocommerce_checkout_fields' , 'add_custom_checkout_city_dropdowns' );
function add_custom_checkout_city_dropdowns( $fields ) {
    $fields['billing']['billing_city']['class'][] = 'update_totals_on_change hidden'; 

    $fields['billing']['billing_city_ua'] = array(
        'label'         => __('City', 'woocommerce'),
        'placeholder'   => _x('billing_city_ua', 'Select your city', 'woocommerce'),
        'required'      => false,
        'class'         => array('form-row-wide cities-select update_totals_on_change hidden'),
        'clear'         => true,
        'type'          => 'select',
        'priority'      => 88,
        'options'       => array(
            ''          => __('Select city', 'woocommerce' ),
            'City1'     => __('City1', 'woocommerce' ),
            'City2'     => __('City2', 'woocommerce' ),
            'City3'     => __('City3', 'woocommerce' ),
            'City4'     => __('City4', 'woocommerce' ),
        ),
    );

    $fields['billing']['billing_city_pl'] = array(
        'label'         => __('City', 'woocommerce'),
        'placeholder'   => _x('billing_city_pl', 'Select your city', 'woocommerce'),
        'required'      => false,
        'class'         => array('form-row-wide cities-select update_totals_on_change hidden'),
        'clear'         => true,
        'type'          => 'select',
        'priority'      => 89, 
        'options'       => array(
            ''          => __('Select city', 'woocommerce' ),
            'City1'     => __('City1', 'woocommerce' ),
            'City2'     => __('City2', 'woocommerce' ),
            'City3'     => __('City3', 'woocommerce' ),
            'City4'     => __('City4', 'woocommerce' ),
        ),
    );
    return $fields;
}

// Custom inline CSS
add_action('wp_head', 'checkout_city_dropdowns_css');
function checkout_city_dropdowns_css() {
    if ( is_checkout() && ! is_wc_endpoint_url() ) : ?>
    <style>
        .cities-select.hidden {display:none;}
        #billing_city_field.hidden {display:none !important;}
    </style>
    <?php endif;
}

// PHP: Remove "(optional)" from some non required fields
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    // Only on checkout page
    if( is_checkout() && ! is_wc_endpoint_url() && in_array($key, ['billing_city_ua', 'billing_city_pl']) ) {
        $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}

// JavaScript: Show/hide City Select fields
add_action( 'woocommerce_checkout_init' , 'checkout_city_dropdowns_js' );
function checkout_city_dropdowns_js() {
    $country  = WC()->customer->get_billing_country();
    $city     = WC()->customer->get_billing_city();

    wc_enqueue_js("
        const city   = '#billing_city',       cityUA  = '#billing_city_ua', 
            cityPL = '#billing_city_pl',    country = '#billing_country';

        var countryVal = '{$country}', 
            cityVal    = '{$city}';

        function showHideCityFields( city, cityUA, cityPL, cityVal, countryVal ) {
            if ( countryVal === 'UA' ) {
                $(city).val(cityVal).closest('p').addClass('hidden');
                $(cityUA).val('').closest('p').removeClass('hidden');
                $(cityPL).val(cityVal).closest('p').addClass('hidden');
            } else if ( countryVal === 'PL' ) {
                $(city).val(cityVal).closest('p').addClass('hidden');
                $(cityUA).val(cityVal).closest('p').addClass('hidden');
                $(cityPL).val('').closest('p').removeClass('hidden');
            } else {
                $(city).val(cityVal).closest('p').removeClass('hidden');
                $(cityPL).val('').closest('p').addClass('hidden');
                $(cityUA).val('').closest('p').addClass('hidden');
            }
        }

        // On Start: Get country value
        if( $(country).val() != '' && $(country).val() != undefined ) {
            countryVal = $(country).val();
        }

        // On Start: Get city value
        if( $(city).val() != '' && $(city).val() != undefined ) {
            cityVal = $(city).val();
            if ( countryVal === 'UA' ) {
                $(cityUA).val(cityVal).change();
            } else if ( countryVal === 'PL' ) {
                $(cityPL).val(cityVal).change();
            }
        }

        // On start: Enable WooCommerce Select2 for custom select fields
        $(cityUA+','+cityPL).selectWoo();

        // On start: Remove '(optional)' from label
        $(document.body).on('update_checkout', function(){
            $(cityUA+'_field label > .optional').remove();
            $(cityPL+'_field label > .optional').remove();
        });

        // On start: Show/Hide city fields
        showHideCityFields( city, cityUA, cityPL, cityVal, countryVal );

        // On Country change: Show/Hide city fields
        $('form.woocommerce-checkout').on('change', country, function() {
            showHideCityFields( city, cityUA, cityPL, '', $(this).val() );
        });

        // For country 'UA', on city change
        $('form.woocommerce-checkout').on('change', cityUA, function() {
            $(city).val($(this).val());
        });

        // For country 'PL', on city change
        $('form.woocommerce-checkout').on('change', cityPL, function() {
            $(city).val($(this).val());
        });
    ");
}

代码位于子主题的函数.php文件中(或插件中)。它应该起作用。

评论

0赞 libertarian 11/18/2023
谢谢你的答案!我正在测试 - 两个国家/地区一切正常,但是当我将第三个国家/地区添加到“开始”部分时,它不起作用。如果我首先选择两个添加中的一个并重新加载页面 - 我看到它的选择,但当第三个 - 不,它的选择不会出现。我在“else”之前添加了另一个“else if”,以及其他带有昏迷的东西 - 随机 CZ、cityCZ = '#billing_city_cz'、函数 showHideCityFields( city, cityUA, cityPL, cityCZ, cityVal, countryVal ) 等,我没有错过它。
0赞 libertarian 11/18/2023
我现在尝试一个接一个地添加,以同样非常苛刻的顺序,而不是随机添加,我认为现在有帮助