Customizing My-Account Addresses Fields in Woocommerce 3

Customizing my-account addresses fields in Woocommerce 3

In My account > Adresses section, the below hooked functions will:

  • remove "Address 2" billing and shipping fields
  • reorder billing and shipping address fields
  • reorder billing Email and phone fields (after first and last names)
  • remove "Address 2" from display

You forgot the "country" field that you can reorder easily in the $sorted_fields array…

The code:

// Account Edit Adresses: Remove and reorder addresses fields
add_filter( 'woocommerce_default_address_fields', 'custom_default_address_fields', 20, 1 );
function custom_default_address_fields( $fields ) {
// Only on account pages
if( ! is_account_page() ) return $fields;

## ---- 1. Remove 'address_2' field ---- ##

unset($fields['address_2']);

## ---- 2. Sort Address fields ---- ##

// Set the order (sorting fields) in the array below
$sorted_fields = array('first_name','last_name','company','address_1','country','postcode','city','state');

$new_fields = array();
$priority = 0;

// Reordering billing and shipping fields
foreach($sorted_fields as $key_field){
$priority += 10;

if( $key_field == 'company' )
$priority += 20; // keep space for email and phone fields

$new_fields[$key_field] = $fields[$key_field];
$new_fields[$key_field]['priority'] = $priority;
}
return $new_fields;
}

// Account Edit Adresses: Reorder billing email and phone fields
add_filter( 'woocommerce_billing_fields', 'custom_billing_fields', 20, 1 );
function custom_billing_fields( $fields ) {
// Only on account pages
if( ! is_account_page() ) return $fields;

## ---- 2. Sort billing email and phone fields ---- ##

$fields['billing_email']['priority'] = 30;
$fields['billing_email']['class'] = array('form-row-first');
$fields['billing_phone']['priority'] = 40;
$fields['billing_phone']['class'] = array('form-row-last');

return $fields;
}

// Account Displayed Addresses : Remove 'address_2'
add_filter( 'woocommerce_my_account_my_address_formatted_address' , 'my_account_address_formatted_addresses', 20, 3 );
function my_account_address_formatted_addresses( $address, $customer_id, $address_type ) {
unset($address['address_2']); // remove Address 2

return $address;
}

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

If you want to make that effective in checkout page too, you will have to remove this lines:

// Only on account pages
if( ! is_account_page() ) return $fields;

In each function (2 times)

Sample Image

Customize addresses fields on WooCommerce My account and Checkout

The hook woocommerce_checkout_fields only allow customizations on checkout page and will not affect the My account "Addresses" section fields.

The following will affect both My account "Addresses" section fields and checkout fields, allowing to make billing and shipping fields customized also on the related my account section.


1) For addresses fields (both billing and shipping) on My account and checkout:

In some cases you need to use this filter for addresses fields and it's applied to all billing and shipping default fields:

// Billing and Shipping fields on my account edit-addresses and checkout
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
function custom_override_default_address_fields( $fields ) {
$fields['first_name']['label'] = 'First name';
$fields['last_name']['label'] = 'Last name';
$fields['company']['label'] = 'Company name';
$fields['address_1']['label'] = 'Street address';
$fields['address_2']['label'] = 'Apartment, unit, etc.';
$fields['city']['label'] = 'City';
$fields['country']['label'] = 'Country';
$fields['state']['label'] = 'County/State';
$fields['postcode']['label'] = 'Postcode';

return $fields;
}

You can use WooCommerce conditional tags is_account_page() and is_checkout() to target my account pages or checkout page…


2) For Billing fields on my account edit-addresses and checkout:

// Billing fields on my account edit-addresses and checkout
add_filter( 'woocommerce_billing_fields' , 'custom_billing_fields' );
function custom_billing_fields( $fields ) {

// Billing Fields
$fields['billing_first_name']['label'] = 'First name';
$fields['billing_last_name']['label'] = 'Last name';
$fields['billing_company']['label'] = 'Company name';
$fields['billing_address_1']['label'] = 'Street address';
$fields['billing_address_2']['label'] = 'Apartment, unit, etc.';
$fields['billing_city']['label'] = 'City';
$fields['billing_country']['label'] = 'Country';
$fields['billing_state']['label'] = 'County/State';
$fields['billing_postcode']['label'] = 'Postcode';
$fields['billing_email']['label'] = 'Email';
$fields['billing_phone']['label'] = 'Phone';

return $fields;
}

3) For Shipping fields on my account edit-addresses and checkout

// Shipping fields on my account edit-addresses and checkout
add_filter( 'woocommerce_shipping_fields' , 'custom_shipping_fields' );
function custom_shipping_fields( $fields ) {

// Shipping Fields
$fields['shipping_first_name']['label'] = 'First name';
$fields['shipping_last_name']['label'] = 'Last name';
$fields['shipping_company']['label'] = 'Company name';
$fields['shipping_address_1']['label'] = 'Street address';
$fields['shipping_address_2']['label'] = 'Apartment, unit, etc.';
$fields['shipping_city']['label'] = 'City';
$fields['shipping_country']['label'] = 'Country';
$fields['shipping_state']['label'] = 'County/State';
$fields['shipping_postcode']['label'] = 'Postcode';
$fields['shipping_email']['label'] = 'Email';
$fields['shipping_phone']['label'] = 'Phone';

return $fields;
}

4) All (other) fields only on checkout:

// All fields only on checkout
add_filter( 'woocommerce_checkout_fields' , 'other_custom_checkout_fields' );
function other_custom_checkout_fields( $fields ) {

// Account Fields
$fields['account']['account_username']['label'] = 'Username or email';
$fields['account']['account_password']['label'] = 'Password';

// Order Fields
$fields['order']['order_comments']['label'] = 'Order notes';

return $fields;
}

5) Also depending on the selected country, you should need to use the filters:

  • woocommerce_country_locale_field_selectors
  • woocommerce_get_country_locale_default

Those are located on WC_Country Class.

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


Related official documentation: Customizing checkout fields using actions and filters

Make fields optional in WooCommerce My account edit addresses

To make all My account > addresses fields optional use the following:

// Make all My account addresses fields optional
add_filter( 'woocommerce_default_address_fields' , 'filter_my_account_addresses_fields', 999 );
add_filter( 'woocommerce_billing_fields', 'filter_my_account_addresses_fields', 999 );
function filter_my_account_addresses_fields( $fields ) {
// Only on My account edit addresses
if ( is_wc_endpoint_url( 'edit-address' ) ) {
// Loop through existing fields
foreach( $fields as $field_key => $field_data ) {
// if they are required
if( $fields[$field_key]['required'] ) {
// Make them optional
$fields[$field_key]['required'] = false;
}
}
}

return $fields;
}

// Optionaly remove ("optional)" text from My account addresses fields
add_filter( 'woocommerce_form_field' , 'remove_account_addresses_optional_fields_label', 10, 4 );
function remove_account_addresses_optional_fields_label( $field, $key, $args, $value ) {
// Only on My account edit addresses
if ( is_wc_endpoint_url( 'edit-address' ) ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}

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

Customizing Woocommerce template my-account/form-edit-addresses

You can NOT change the <p> tag (removing all existing attributes + values) to a <div> as will certainly break some processes, because specific woocommerce javascript is enabled on this…

Now you can use woocommerce_form_field_args filter hook to change the class globally on all the <p> tags and you can remove the required behavior on all the fields too, so <abbr class="required" title="required">*</abbr> will be removed.

Here is that code:

add_filter( 'woocommerce_form_field_args', 'custom_wc_form_field_args', 10, 3 );
function custom_wc_form_field_args( $args, $key, $value ){
// Only on My account > Edit Adresses
if( is_wc_endpoint_url( 'edit-account' ) || is_checkout() ) return $args;

$args['class'] = array('form-input-group');
$args['required'] = false;

return $args;
}

So you will have to manage CSS to make design changes.

All available arguments $args in this array are:

'type'              # @ string
'label' # @ string
'description' # @ string
'placeholder' # @ string
'maxlength' # @ boolean
'required' # @ boolean
'autocomplete' # @ boolean
'id' # => $key (argument)
'class' # @ array
'label_class' # @ array
'input_class' # @ array
'return' # @ boolean
'options' # @ array
'custom_attributes' # @ array
'validate' # @ array
'default' # @ string
'autofocus' # @ string
'priority' # @ string

With woocommerce_form_field_{field_type} filter hook you can access to field settings individually based on the field type. This hook has 4 available arguments: $field, $key, $args and $value

Add custom fields to WooCommerce new account Page

The following will optimize and compact your code, adding field validation and allowing to save all fields values as user meta data:

// Custom function with all extra field data arrays
function extra_register_fields() {
$text_domain = 'woocommerce';
return array(
'first_name' => array('type' => 'text', 'class' => ['form-row-first'], 'required' => 1, 'label' => __('First name', $text_domain) ),
'last_name' => array('type' => 'text', 'class' => ['form-row-last'], 'required' => 1, 'label' => __('Last name', $text_domain) ),
'phone' => array('type' => 'tel', 'class' => ['form-row-wide'], 'required' => 1, 'label' => __( 'Phone', $text_domain ) ),
'facebook' => array('type' => 'text', 'class' => ['form-row-wide'], 'required' => 1, 'label' => __( 'Facebook ', $text_domain ) ),
'whatsapp' => array('type' => 'text', 'class' => ['form-row-wide'], 'required' => 1, 'label' => __( 'WhatsApp', $text_domain ) ),
'country' => array('type' => 'country', 'class' => ['address-field'], 'required' => 1, 'label' => __( 'Country', $text_domain ) ),
'state' => array('type' => 'state', 'class' => ['address-field'], 'required' => 1, 'label' => __( 'State', $text_domain ) ),
);
}

// Add extra register fields
add_action( 'woocommerce_register_form_start', 'wooc_extra_register_fields' );
function wooc_extra_register_fields() {
foreach ( extra_register_fields() as $fkey => $values ) {
if( $fkey === 'phone' ) $values['clear'] = 1;
if( $fkey === 'state' ) $values['validate'] = ['state'];

$value = isset($_POST['billing_'.$fkey]) ? esc_attr($_POST['billing_'.$fkey]) : '';

woocommerce_form_field( 'billing_'.$fkey, $values, $value );
}
wp_enqueue_script('wc-country-select', get_site_url().'/wp-content/plugins/woocommerce/assets/js/frontend/country-select.min.js', array('jquery'), true);
}

// Extra register fields validation
add_action( 'woocommerce_register_post', 'wc_validate_reg_form_fields', 10, 3 );
function wc_validate_reg_form_fields( $username, $email, $validation_errors ) {
foreach ( extra_register_fields() as $fkey => $values ) {
if (isset($_POST['billing_'.$fkey]) && empty($_POST['billing_'.$fkey]) && $values['required'] ) {
$validation_errors->add( 'extra_fields', sprintf('%s is a required field', $values['label']) );
}
}
return $validation_errors;
}

// Save extra register fields values
add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' );
function wooc_save_extra_register_fields( $customer_id ) {
foreach( extra_register_fields() as $fkey => $values ) {
if ( isset($_POST['billing_'.$fkey]) ) {
$value = in_array($fkey, ['country', 'state']) ? sanitize_text_field($_POST['billing_'.$fkey]) : esc_attr($_POST['billing_'.$fkey]);

update_user_meta( $customer_id, 'billing_'.$fkey, $value );

if ( in_array($fkey, ['first_name', 'last_name']) )
update_user_meta( $customer_id, $fkey, $value );
}
}
}

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


To display "Facebook" and "WhatsApp" fields in My account edit billing address use the following:

// Display Facebook and WhatsApp fields in My account eddit billing address
add_filter( 'woocommerce_billing_fields', 'additional_billing_fields', 20, 1 );
function additional_billing_fields($billing_fields) {
if ( is_wc_endpoint_url( 'edit-address' ) ) {
foreach ( extra_register_fields() as $fkey => $values ) {
if ( in_array($fkey, ['facebook', 'whatsapp']) ) {
$billing_fields['billing_'.$fkey] = $values;
}
}
}
return $billing_fields;
}

To add "Facebook" and "WhatsApp" fields to Admin user billing section use the following:

// WordPress User: Add Facebook and WhatsApp fields to billing section
add_filter('woocommerce_customer_meta_fields', 'wordpress_user_account_billing_birthdate_field');
function wordpress_user_account_billing_birthdate_field( $fields ) {
foreach ( extra_register_fields() as $fkey => $values ) {
if ( in_array($fkey, ['facebook', 'whatsapp']) ) {
$fields['billing']['fields']['billing_'.$fkey] = array(
'label' => $values['label'],
'description' => ''
);
}
}
return $fields;
}


Related Topics



Leave a reply



Submit