2

I have added the city field as a dropdown list but I can't get it to show up in the backend. https://ibb.co/3rdsQpY

/* city dropdown */

// UPDATE CHECKOUT CITY FIELD
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
add_filter('woocommerce_admin_shipping_fields', 'custom_override_default_address_fields');// manual order


function custom_override_default_address_fields( $address_fields ) {

    // Billing City
    $address_fields['city']['type'] = 'select';
    $address_fields['city']['label'] = __('City', 'custom-domain');
    $address_fields['city']['priority'] = '41';
    $address_fields['city']['class'] = array('my-field-class form-row-last');
    $address_fields['city']['options'] = array(
       // '' => __( 'Select unit type' ),    /*= this will make empty field*/
        'Jeddah' => __('Jeddah', 'custom-domain'),
    );

    // Sort
    ksort($address_fields['city']['options']);


    return $address_fields;
}

I tried to add the filter below but it didn't work. what am I missing?

add_filter( 'woocommerce_customer_meta_fields', 'custom_override_default_address_fields' );
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Bassam Radi
  • 169
  • 9

1 Answers1

2

The following will change billing and shipping city fields to a dropdown on

  • Checkout city fields
  • My account edit address city fields
  • Admin Single Order pages: edit billing and shipping city fields
  • Admin Users pages: edit billing and shipping city fields

The code:

// Custom function that handle city options
function get_city_options() {
    $options = array(
        // '' => __( 'Select unit type' ),    /*= this will make empty field*/
        'Jeddah' => __('Jeddah', 'custom-domain'),
    );
    ksort($options);

    return $options;
}

// Checkout and my account (edit) billing and shipping city
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_city_fields' );
function custom_override_default_city_fields( $fields ) {
    $fields['city']['type'] = 'select';
    $fields['city']['class'] = array('my-field-class form-row-last');
    $fields['city']['input_class'] = array('state_select');
    $fields['city']['options'] = get_city_options();
    $fields['city']['priority'] = '41';

    return $fields;
}

// Admin editable single orders billing and shipping city field
add_filter('woocommerce_admin_billing_fields', 'admin_order_pages_city_fields');
add_filter('woocommerce_admin_shipping_fields', 'admin_order_pages_city_fields');
function admin_order_pages_city_fields( $fields ) {
    $fields['city']['type']    = 'select';
    $fields['city']['options'] = get_city_options();
    $fields['city']['class']   = 'short'; // Or 'js_field-country select short' to enable selectWoo (select2).

    return $fields;
}

// Admin editable User billing and shipping city
add_filter( 'woocommerce_customer_meta_fields', 'custom_override_user_city_fields' );
function custom_override_user_city_fields( $fields ) {
    $fields['billing']['fields']['billing_city']['type']    = $fields['shipping']['fields']['shipping_city']['type']  = 'select';
    $fields['billing']['fields']['billing_city']['options'] = $fields['shipping']['fields']['shipping_city']['options'] = get_city_options();

    return $fields;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.


Addition - Other billing and shipping fields

For other billing and shipping fields than WooCommerce default addresses fields you can replace:

// Checkout and my account (edit) billing and shipping city
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_city_fields' );
function custom_override_default_city_fields( $fields ) {
    // … …
    return $fields;
}

by the 2 following hooked functions:

// For billing custom field (Checkout and my account edit addresses):
add_filter( 'woocommerce_billing_fields' , 'custom_override_billing_fields' );
function custom_override_billing_fields( $fields ) {
    $fields['billing_custom1'] = array(
        'type' => 'text', // chose the field type
        'label' =>  __('Custom label (billing)',  'woocommerce' ),
        'class' => array('form-row-wide'), // can be also 'form-row-first' or 'form-row-last'
        'required' => false, // Optional
        'clear' => true, // Optional
        'priority' => 200, // To change the field location increase or decrease this value
    );
    return $fields;
}

// For shipping custom field (Checkout and my account edit addresses):
add_filter( 'woocommerce_shipping_fields' , 'custom_override_shipping_fields' );
function custom_override_shipping_fields( $fields ) {
    $fields['shipping_custom1'] = array(
        'type' => 'text', // chose the field type
        'label' =>  __('Custom label (shipping)',  'woocommerce' ),
        'class' => array('form-row-wide'), // can be also 'form-row-first' or 'form-row-last'
        'required' => false, // Optional
        'clear' => true, // Optional
        'priority' => 200, // To change the field location increase or decrease this value
    );
    return $fields;
}
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Now that's how every customized code should be to be included everywhere as you mentioned: .Checkout city fields. .My account edit address city fields. .Admin Single Order pages: edit billing and shipping city fields. .Admin Users pages: edit billing and shipping city fields. I mean what's the point of adding a code only in the checkout. I'll take this code for a reference for other customized fields I have. – Bassam Radi Sep 27 '20 at 19:34
  • 1
    For other fields than WooCommerce default addresses fields, use `woocommerce_shipping_fields` and `woocommerce_shipping_fields` instead of `woocommerce_default_address_fields` hook like explained in [here](https://stackoverflow.com/questions/54421397/woocommerce-checkout-fields-settings-and-customization-hooks/54425615#54425615) or in [here](https://stackoverflow.com/questions/53851571/customize-some-checkout-fields-placeholders-in-woocommerce-3/53853215#53853215) – LoicTheAztec Sep 27 '20 at 20:21
  • I have created a new field. everything is good so far but in the manual new order "woocommerce_admin_shipping_fields" I have set the type to 'text' and the new field is showing as a drop down. Why is that? – Bassam Radi Sep 28 '20 at 18:05
  • ok, I got it to work. I removed the class "js_field-country select" and kept the "short" class and now it's working. However, the field does not pull the saved data from the user. – Bassam Radi Sep 28 '20 at 18:31
  • @BassamRadi There is something strange in your case, as woocommerce_customer_meta_fields hook display **and save** billing and shipping user fields… – LoicTheAztec Sep 28 '20 at 19:20
  • Maybe because they are a new field. I'll post the code in a new question. – Bassam Radi Sep 28 '20 at 22:22
  • @BassamRadi That is not the problem… see [all this related working answer threads](https://stackoverflow.com/search?q=user%3A3730754+woocommerce_customer_meta_fields) that are using that hook. On My test server with last WooCommerce version everything works fine. And remember that the city field already exist and is saved on submit. So there is something else in your case that is making trouble. – LoicTheAztec Sep 28 '20 at 22:26
  • yeah, I am trying to figure it out. I am reading more about it. I will update once it works. – Bassam Radi Sep 28 '20 at 22:48