You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce个人资料编辑页街道字段保存异常问题排查

问题排查与解决方案:WooCommerce动态街道字段保存与回显问题

问题现象

  • 个人资料编辑页提示字段已保存,但订单完成页不显示所选街道
  • 账户城市字段可同步到结账页,但重新编辑账户时街道字段为空,未正确保存

问题原因

  1. 字段初始化逻辑缺失:编辑地址页加载时,未根据用户已保存的城市值匹配对应街道选项,导致已保存的街道值不在当前选项列表中,无法回显
  2. JS渲染逻辑漏洞:页面初始化时仅渲染街道选项,未自动选中已保存的街道值
  3. 默认值未关联用户数据:字段设置时未调用用户已保存的地址数据,导致编辑页加载时无预填内容

完整修复代码

// Settings
function cities_areas_settings() {
    $text_domain = 'woocommerce';
    return array(
        ''      => array(),
        'Test'  => array( 
            __('Street 2', $text_domain),
            __('Street 3', $text_domain),
            __('Street 4', $text_domain),
        ),
        'Test1' => array(
            __('Street 5', $text_domain),
            __('Street 6', $text_domain),
        ),
        'Test2' => array( 
            __('Street 7', $text_domain),
            __('Street 8', $text_domain),
        ),
        'Test3' => array(
            __('Street 9', $text_domain),
            __('Street 10', $text_domain),
        ),
    );
}

// Utility function
function get_initial_options_arrays() {
    $text_domain = 'woocommerce';
    return array(
        'text_domain'   => 'woocommerce',
        'option_cities' => array('' => __('Select your City', $text_domain)),
        'select_areas'  => array('' => __('Select your street', $text_domain)),
        'test_areas'    => array('' => __('Select your street', $text_domain)),
        'test1_areas'   => array('' => __('Select your street', $text_domain)),
        'test2_areas'   => array('' => __('Select your street', $text_domain)),
        'test3_areas'   => array('' => __('Select your street', $text_domain)),
    );
}

// Utility function
function get_basic_options_fields() {
    extract(get_initial_options_arrays());

    foreach (cities_areas_settings() as $city => $zone) {
        $option_cities[$city] = $city; 

        if ($city === '') {
            foreach ($zone as $area) { 
                $select_areas[$area] = $area; 
            }
        } 
    }
    return array( 'option_cities' => $option_cities, 'select_areas' => $select_areas );
}

// Billing fields
add_filter('woocommerce_billing_fields', 'custom_billing_fields');
function custom_billing_fields($fields) {
    extract(get_initial_options_arrays());
    extract(get_basic_options_fields());
    
    // 获取当前用户已保存的账单地址数据
    $user_id = get_current_user_id();
    $saved_city = $user_id ? get_user_meta($user_id, 'billing_city', true) : '';
    $saved_street = $user_id ? get_user_meta($user_id, 'billing_address_1', true) : '';

    $fields['billing_city']['type'] = 'select'; 
    $fields['billing_city']['class'] = array('form-row-first');
    $fields['billing_city']['input_class'] = array('state_select');
    $fields['billing_city']['options'] = $option_cities;
    // 设置已保存的城市为默认值
    if (!empty($saved_city)) {
        $fields['billing_city']['default'] = $saved_city;
    }

    $fields['billing_address_1'] = array(
        'type' => 'select',
        'label' => __('Street', $text_domain),
        'class' => array('form-row-last'),
        'input_class' => array('state_select'),
        'options' => $select_areas,
        'required' => true,
        'default' => $saved_street, // 设置已保存的街道为默认值
        'priority' => 50,
    );

    return $fields;
}

// Shipping fields
add_filter('woocommerce_shipping_fields', 'custom_shipping_fields');
function custom_shipping_fields($fields) {
    extract(get_initial_options_arrays());
    extract(get_basic_options_fields());
    
    // 获取当前用户已保存的配送地址数据
    $user_id = get_current_user_id();
    $saved_city = $user_id ? get_user_meta($user_id, 'shipping_city', true) : '';
    $saved_street = $user_id ? get_user_meta($user_id, 'shipping_address_1', true) : '';

    // Modify shipping city field
    $fields['shipping_city']['type'] = 'select';
    $fields['shipping_city']['class'] = array('form-row-first');
    $fields['shipping_city']['input_class'] = array('state_select');
    $fields['shipping_city']['options'] = $option_cities;
    // 设置已保存的城市为默认值
    if (!empty($saved_city)) {
        $fields['shipping_city']['default'] = $saved_city;
    }

    // Add shipping address_1 field
    $fields['shipping_address_1'] = array(
        'type' => 'select',
        'label' => __('Street', $text_domain),
        'class' => array('form-row-last'),
        'input_class' => array('state_select'),
        'options' => $select_areas,
        'required' => true,
        'default' => $saved_street, // 设置已保存的街道为默认值
        'priority' => 50,
    );

    return $fields;
}

// Jquery code
add_action('wp_footer', 'custom_checkout_js_script');
function custom_checkout_js_script() {
    if ( ( is_checkout() && !is_wc_endpoint_url() ) || is_wc_endpoint_url( 'edit-address' ) ) :
        extract(get_initial_options_arrays());
        $settings = cities_areas_settings(); 
        
        foreach ($settings['Test'] as $area) { 
            $test_areas[$area] = $area; 
        }
        foreach ($settings['Test1'] as $area) { 
            $test1_areas[$area] = $area; 
        }
        foreach ($settings['Test2'] as $area) { 
            $test2_areas[$area] = $area; 
        }
        foreach ($settings['Test3'] as $area) {
            $test3_areas[$area] = $area; 
        }
        
        // 获取已保存的街道值
        $user_id = get_current_user_id();
        $saved_billing_street = $user_id ? get_user_meta($user_id, 'billing_address_1', true) : '';
        $saved_shipping_street = $user_id ? get_user_meta($user_id, 'shipping_address_1', true) : '';
        ?>
        <script id="custom-js" language="javascript">
            jQuery(function($) {
                var a = 'select[name="billing_city"]',
                    b = 'select[name="billing_address_1"]',
                    c = 'select[name="shipping_city"]',
                    d = 'select[name="shipping_address_1"]',
                    l = <?php echo json_encode($test_areas); ?>,
                    o = <?php echo json_encode($test1_areas); ?>,
                    r = <?php echo json_encode($test2_areas); ?>,
                    i = <?php echo json_encode($test3_areas); ?>,
                    w = '<?php echo is_checkout() ? 'form.woocommerce-checkout' : 'form'; ?>',
                    s = $(b).html(),
                    t = $(d).html(),
                    savedBillingStreet = '<?php echo esc_js($saved_billing_street); ?>',
                    savedShippingStreet = '<?php echo esc_js($saved_shipping_street); ?>';

                function dynamicSelectOptions(opt, sel, selectedVal) {
                    var options = '';
                    $.each(opt, function(key, value) {
                        // 匹配已保存的值,设置选中状态
                        var selected = (key === selectedVal) ? 'selected' : '';
                        options += '<option value="' + key + '" ' + selected + '>' + value + '</option>';
                    }); 
                    $(sel).html(options);
                }
                
                function dynamicSelectOptionsApply( val, e, l, o, r, i, f = false, selectedVal = '' ) {
                    if (val === 'Test') {
                        dynamicSelectOptions(l, e, selectedVal);
                    } else  if (val === 'Test1') {
                        dynamicSelectOptions(o, e, selectedVal);
                    } else if (val === 'Test2') { 
                        dynamicSelectOptions(r, e, selectedVal);
                    } else if (val === 'Test3') {
                        dynamicSelectOptions(i, e, selectedVal);
                    } else if ( f !== false ) {
                        // 恢复初始选项并设置选中值
                        $(e).html(s);
                        if (selectedVal) {
                            $(e).val(selectedVal);
                        }
                    }
                }
                // On start after DOM is loaded
                dynamicSelectOptionsApply($(a).val(), b, l, o, r, i, false, savedBillingStreet);
                dynamicSelectOptionsApply($(c).val(), d, l, o, r, i, false, savedShippingStreet);

                // On change event
                $(w).on('change', a, function() { 
                    dynamicSelectOptionsApply( $(this).val(), b, l, o, r, i, s );
                })
                $(w).on('change', c, function() { 
                    dynamicSelectOptionsApply( $(this).val(), d, l, o, r, i, t );
                });
            });
        </script>
    <?php
    endif;
}

修复说明

  1. 关联用户保存数据:在账单/配送字段设置中,获取用户已保存的城市和街道值,设置为字段默认值,确保页面加载时预填内容
  2. 优化JS选项渲染:修改dynamicSelectOptions函数,添加选中值参数,渲染街道选项时自动匹配已保存的街道值
  3. 完善初始化逻辑:页面加载时调用渲染函数并传入已保存的街道值,确保对应城市的街道列表渲染后自动选中正确选项
  4. 清理调试代码:移除原代码中的调试输出语句,避免干扰页面正常渲染

内容的提问来源于stack exchange,提问作者brc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:04:51