如何在WooCommerce账户地址编辑页实现动态联动下拉字段
问题描述
基于Stack Overflow示例代码修改后,我已在WooCommerce结账页成功实现城市与街道的动态联动下拉字段功能。现需将该功能同步至用户账户的地址编辑页面,使其效果与结账页一致。尝试添加woocommerce_default_address_fields等多个钩子后未生效,请问该如何实现?
现有结账页功能实现代码:
function cities_areas_settings() { $text_domain = 'woocommerce'; return array( __('', $text_domain) => array( ), __('Test', $text_domain) => array( __('Street 2', $text_domain), __('Street 3', $text_domain), __('Street 4', $text_domain), ), __('Test1', $text_domain) => array( __('Street 5', $text_domain), __('Street 6', $text_domain), ), __('Test2', $text_domain) => array( __('Street 7', $text_domain), __('Street 8', $text_domain), ), __('Test3', $text_domain) => array( __('Street 9', $text_domain), __('Street 10', $text_domain), ), ); } add_filter('woocommerce_checkout_fields', 'custom_checkout_fields'); function custom_checkout_fields($fields) { $text_domain = 'woocommerce'; $option_cities = array(); $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)); foreach (cities_areas_settings() as $city => $zone) { $option_cities[$city] = $city; if ($city === '') { foreach ($zone as $area) { $select_areas[$area] = $area; } } elseif ($city === 'Test') { foreach ($zone as $area) { $test_areas[$area] = $area; } } elseif ($city === 'Test1') { foreach ($zone as $area) { $test1_areas[$area] = $area; } } elseif ($city === 'Test2') { foreach ($zone as $area) { $test2_areas[$area] = $area; } } } $fields['billing']['billing_city']['type'] = 'select'; $fields['billing']['billing_city']['class'] = array('form-row-first'); $fields['billing']['billing_city']['input_class'] = array('state_select'); $fields['billing']['billing_city']['options'] = $option_cities; $fields['shipping']['shipping_city']['type'] = 'select'; $fields['shipping']['shipping_city']['class'] = array('form-row-first'); $fields['shipping']['shipping_city']['input_class'] = array('state_select'); $fields['shipping']['shipping_city']['options'] = $option_cities; $fields['billing']['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' => '', 'priority' => 50, ); $fields['shipping']['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' => '', 'priority' => 50, ); return $fields; } add_action('wp_footer', 'custom_checkout_js_script'); function custom_checkout_js_script() { if (is_checkout() && !is_wc_endpoint_url()) : $text_domain = 'woocommerce'; $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)); $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; } ?> <script language="javascript"> jQuery(function($) { var a = 'select[name="billing_city"]', b = 'select[name="billing_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); ?>, s = $(b).html(); function dynamicSelectOptions(opt) { var options = ''; $.each(opt, function(key, value) { options += '<option value="' + key + '">' + value + '</option>'; }); $(b).html(options); } if ($(a).val() === 'Test') { dynamicSelectOptions(l); } else if ($(a).val() === 'Test1') { dynamicSelectOptions(o); } else if ($(a).val() === 'Test2') { dynamicSelectOptions(r); } else if ($(a).val() === 'Test3') { dynamicSelectOptions(i); } console.log($(a).val()); $('form.woocommerce-checkout').on('change', a, function() { console.log($(this).val()); if ($(this).val() === 'Test') { dynamicSelectOptions(l); } else if ($(this).val() === 'Test1') { dynamicSelectOptions(o); } else if ($(this).val() === 'Test2') { dynamicSelectOptions(r); } else if ($(this).val() === 'Test3') { dynamicSelectOptions(i); } else { $(b).html(s); } }); }); </script> <script language="javascript"> jQuery(function($) { var a = 'select[name="shipping_city"]', b = '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); ?>, s = $(b).html(); function dynamicSelectOptions(opt) { var options = ''; $.each(opt, function(key, value) { options += '<option value="' + key + '">' + value + '</option>'; }); $(b).html(options); } if ($(a).val() === 'Test') { dynamicSelectOptions(l); } else if ($(a).val() === 'Test1') { dynamicSelectOptions(o); } else if ($(a).val() === 'Test2') { dynamicSelectOptions(r); } else if ($(a).val() === 'Test3') { dynamicSelectOptions(i); } console.log($(a).val()); $('form.woocommerce-checkout').on('change', a, function() { console.log($(this).val()); if ($(this).val() === 'Test') { dynamicSelectOptions(l); } else if ($(this).val() === 'Test1') { dynamicSelectOptions(o); } else if ($(this).val() === 'Test2') { dynamicSelectOptions(r); } else if ($(this).val() === 'Test3') { dynamicSelectOptions(i); } else { $(b).html(s); } }); }); </script> <?php endif; }
解决方案
要在账户地址编辑页实现相同联动效果,需针对账户页的字段钩子和页面判断做调整,完整修改后的代码如下:
function cities_areas_settings() { $text_domain = 'woocommerce'; return array( __('', $text_domain) => array( ), __('Test', $text_domain) => array( __('Street 2', $text_domain), __('Street 3', $text_domain), __('Street 4', $text_domain), ), __('Test1', $text_domain) => array( __('Street 5', $text_domain), __('Street 6', $text_domain), ), __('Test2', $text_domain) => array( __('Street 7', $text_domain), __('Street 8', $text_domain), ), __('Test3', $text_domain) => array( __('Street 9', $text_domain), __('Street 10', $text_domain), ), ); } // 处理结账页字段 add_filter('woocommerce_checkout_fields', 'custom_checkout_fields'); // 处理账户地址页的账单字段 add_filter('woocommerce_billing_fields', 'custom_address_fields'); // 处理账户地址页的配送字段 add_filter('woocommerce_shipping_fields', 'custom_address_fields'); function custom_checkout_fields($fields) { return custom_address_fields($fields); } function custom_address_fields($fields) { $text_domain = 'woocommerce'; $option_cities = array(); $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)); foreach (cities_areas_settings() as $city => $zone) { $option_cities[$city] = $city; if ($city === '') { foreach ($zone as $area) { $select_areas[$area] = $area; } } elseif ($city === 'Test') { foreach ($zone as $area) { $test_areas[$area] = $area; } } elseif ($city === 'Test1') { foreach ($zone as $area) { $test1_areas[$area] = $area; } } elseif ($city === 'Test2') { foreach ($zone as $area) { $test2_areas[$area] = $area; } } } // 修改城市字段为下拉选择 if (isset($fields['billing_city'])) { $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 (isset($fields['shipping_city'])) { $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 (isset($fields['billing_address_1'])) { $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' => '', 'priority' => 50, ); } if (isset($fields['shipping_address_1'])) { $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' => '', 'priority' => 50, ); } return $fields; } add_action('wp_footer', 'custom_address_js_script'); function custom_address_js_script() { // 同时匹配结账页和账户地址编辑页 if (is_checkout() && !is_wc_endpoint_url() || is_account_page() && isset($_GET['edit-address'])) : $text_domain = 'woocommerce'; $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)); $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; } ?> <script language="javascript"> jQuery(function($) { // 处理账单地址联动 var billingCity = 'select[name="billing_city"]', billingStreet = 'select[name="billing_address_1"]', testAreas = <?php echo json_encode($test_areas); ?>, test1Areas = <?php echo json_encode($test1_areas); ?>, test2Areas = <?php echo json_encode($test2_areas); ?>, test3Areas = <?php echo json_encode($test3_areas); ?>, defaultStreetHtml = $(billingStreet).html(); function dynamicSelectOptions(selectEl, options) { var optionsHtml = ''; $.each(options, function(key, value) { optionsHtml += '<option value="' + key + '">' + value + '</option>'; }); $(selectEl).html(optionsHtml); } // 页面加载时初始化街道选项 if ($(billingCity).val() === 'Test') { dynamicSelectOptions(billingStreet, testAreas); } else if ($(billingCity).val() === 'Test1') { dynamicSelectOptions(billingStreet, test1Areas); } else if ($(billingCity).val() === 'Test2') { dynamicSelectOptions(billingStreet, test2Areas); } else if ($(billingCity).val() === 'Test3') { dynamicSelectOptions(billingStreet, test3Areas); } // 城市选择变化时更新街道 $('form').on('change', billingCity, function() { if ($(this).val() === 'Test') { dynamicSelectOptions(billingStreet, testAreas); } else if ($(this).val() === 'Test1') { dynamicSelectOptions(billingStreet, test1Areas); } else if ($(this).val() === 'Test2') { dynamicSelectOptions(billingStreet, test2Areas); } else if ($(this).val() === 'Test3') { dynamicSelectOptions(billingStreet, test3Areas); } else { $(billingStreet).html(defaultStreetHtml); } }); // 处理配送地址联动 var shippingCity = 'select[name="shipping_city"]', shippingStreet = 'select[name="shipping_address_1"]'; // 页面加载时初始化街道选项 if ($(shippingCity).val() === 'Test') { dynamicSelectOptions(shippingStreet, testAreas); } else if ($(shippingCity).val()
相关产品推荐
相关产品推荐

