Woocommerce overwriting Shipping City Select Field

We are attempting to modify the default Woocommerce Checkout Shipping City Field using the documented methods on docs.woothemes but have run into an issue.

We have replaced the shipping_city text field with a select dropdown menu.

Read More

On page load the select dropdown menu is replaced with the default text field and if available is autofilled with the users previous delivery destination.

However, if the page is reloaded/refreshed the text field is then replaced with the new and much desired select dropdown menu.

We have filtered the field using several WordPress add_filter functions and changed priority both up and down (-999 to 999).

We have run the filter both inside and outside of our Shipping Method Class

We have even disabled the browser auto form complete because we… well ran out of other ideas…

When the select field is working… it works well. The Shipping costs get updated, data gets returned, stored and emailed.

The filters used are:

add_filter( 'woocommerce_checkout_fields', array( $this, 'fn_name' ) );

add_filter( 'woocommerce_default_address_fields', array( $this, 'fn_name' ) );

and the $field array looks like:

$fields[ 'shipping' ][ 'shipping_city' ] = array(
                    'label' => __( 'Suburb/City', 'woocommerce' ),
                    'required' => FALSE,
                    'clear' => TRUE,
                    'type' => 'select',
                    'options' => $options_array,
                    'class' => array( 'update_totals_on_change' )
                );

                return $fields;

Oddly, when we ran two filters on the same field; the label of the sendond was overwritten by the first… go figure… Gee I wish I knew Ajax… i think its Ajax but then if I knew AJAX I’d know if it was Ajax…

WordPress Version 4.5.2 && WooCommerce Version 2.5.5

Addendum regarding final accepted solution:

The code suggested and supplied by @LoicTheAztec worked very well and has been included in our implementation.

However, the issue was caused by our original inclusion of the $field filter inside of our Shipping Method Class which is hooked into the shipping_class_init

To correct the issue we have moved the new woocommerce_form_field_args filter into a seperate file and retrieved our options array after the new Shipping Method Class has worked its magic.

Related posts

Leave a Reply

2 comments

  1. This should work with woocommerce_form_field_args hook, this way:

    add_filter( 'woocommerce_form_field_args', 'custom_form_field_args', 10, 3 );
    function custom_form_field_args( $args, $key, $value ) { 
        if ( $args['id'] == 'billing_city' ) {
         $args = array(
                'label' => __( 'Suburb/City', 'woocommerce' ),
                'required' => FALSE,
                'clear' => TRUE,
                'type' => 'select',
                'options' => $options_array,
                'class' => array( 'update_totals_on_change' )
            );
        } // elseif … and go on 
    
        return $args;
    };
    

    This are he default $args parameter values:

    $defaults = array(
        'type'              => 'text',
        'label'             => '',
        'description'       => '',
        'placeholder'       => '',
        'maxlength'         => false,
        'required'          => false,
        'autocomplete'      => false,
        'id'                => $key,
        'class'             => array(),
        'label_class'       => array(),
        'input_class'       => array(),
        'return'            => false,
        'options'           => array(),
        'custom_attributes' => array(),
        'validate'          => array(),
        'default'           => '',
    );
    

    References:

  2. Put this code into your child theme function.php and should do the job

    $city_args = wp_parse_args( array(
        'type' => 'select',
        'options' => array(
            'city1' => 'Amsterdam',
            'city2' => 'Rotterdam',
            'city3'  => 'Den Haag', 
        ),
    ), $fields['shipping']['shipping_city'] );
    
    $fields['shipping']['shipping_city'] = $city_args;
    $fields['billing']['billing_city'] = $city_args; // Also change for billing field
    
    return $fields;
    
    }
    add_filter( 'woocommerce_checkout_fields', 'jeroen_sormani_change_city_to_dropdown' );