-1

Based on the code from the answer here Show sub Areas dropdown based on chosen city in WooCommerce checkout, I successfully made some changes in the code to fit my needs:

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

The code works correctly on the checkout page.

Now I would display those selectable fields in the customer My Account Edit Address section and wake them work just like in the checkout page.

I looked at the answer here Change WooCommerce city fields to a dropdown in frontend and admin, but I can't figure out how to do it.

I tried to add the following hooks in the code:

add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_city_fields' ); add_filter('woocommerce_admin_billing_fields', 'admin_order_pages_city_fields'); add_filter('woocommerce_admin_shipping_fields', 'admin_order_pages_city_fields'); add_filter( 'woocommerce_customer_meta_fields', 'custom_override_user_city_fields' ); 

But it is not working. How could I make those fields be displayed in the customer's profile?

1
  • The rule in Stack Overflow is one question at the time, so you will ask a new question for the admin area part, later on. Commented Jul 5, 2023 at 20:29

1 Answer 1

0

The code below is just For My Account Edit Address.

The rule in Stack Overflow is one question at the time, so you will ask a new question for the admin area.

The hook woocommerce_checkout_fields only target checkout fields. TO target at the same time, Checkout and My account Address fields, you need to use:

  • woocommerce_billing_fields (for billing fields)
  • woocommerce_shipping_fields (for shipping fields)

For the jQuery code, the selector form is different in My Account Edit Address.

I have revised completely your code:

// 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()); $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; $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, ); 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()); $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['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; } // 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; } ?> <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(); function dynamicSelectOptions(opt, sel) { var options = ''; $.each(opt, function(key, value) { options += '<option value="' + key + '">' + value + '</option>'; }); $(sel).html(options); } function dynamicSelectOptionsApply( val, e, l, o, r, i, f = false ) { if (val === 'Test') { dynamicSelectOptions(l, e); } else if (val === 'Test1') { dynamicSelectOptions(o, e); } else if (val === 'Test2') { dynamicSelectOptions(r, e); } else if (val === 'Test3') { dynamicSelectOptions(i, e); } else if ( f !== false ) { $(e).html(s); } } // On start after DOM is loaded dynamicSelectOptionsApply($(a).val(), b, l, o, r, i ); dynamicSelectOptionsApply($(c).val(), d, l, o, r, i ); // 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; echo '<pre> endpoint_url "edit-address": ' . print_r(is_wc_endpoint_url( 'edit-address' )) . '</pre>'; } 

Tested and works on checkout and on My account Edit Address

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much for your help! Unfortunately, the code does not work correctly. Checkout page: - in the invoicing area of the order in Checkout page, the fields are displayed correctly, but the error "Internal Server Error" appears when placing the order. - in the delivery area, the city and the street are not selectable fields and there is an additional field that has the text "array" inside - the error appears in the delivery area /wp-includes/formatting.php on line 1098
Customer account: - in the billing area, everything works correctly (including saving the information after selecting the city and street). The only problem (if this were a problem) would be that when re-editing the profile and completing the order, the street no longer appears as selected (not being a big problem, you can go without it). - in the delivery area, the city and the street are not selectable fields and an additional field has appeared (everything the same as in the shipping area of the Checkout page)
I will check that when I will have some time for it… But you have the right hooks and the right way to make it work for checkout and my account pages.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.