Reordering Checkout Fields in Woocommerce 3

Reordering checkout fields in WooCommerce 3

For WooCommerce 3+ (update):

Since WooCommerce 3.0 checkout fields have changed a little bit so is not possible to reorder fields as before.

There is a new 'priority' argument that handle fields order, for checkout fields and my account fields as well.

Here is fully functional example for WooCommerce 3+:

// REORDERING CHECKOUT BILLING FIELDS (WOOCOMMERCE 3+)
add_filter( "woocommerce_checkout_fields", "reordering_checkout_fields", 15, 1 );
function reordering_checkout_fields( $fields ) {

## ---- 1. REORDERING BILLING FIELDS ---- ##

// Set the order of the fields
$billing_order = array(
'billing_first_name',
'billing_last_name',
'billing_email',
'billing_phone',
'billing_company',
'billing_address_1',
'billing_address_2',
'billing_postcode',
'billing_city',
'billing_state',
'billing_country'
);

$count = 0;
$priority = 10;

// Updating the 'priority' argument
foreach($billing_order as $field_name){
$count++;
$fields['billing'][$field_name]['priority'] = $count * $priority;
}

## ---- 2. CHANGING SOME CLASSES FOR BILLING FIELDS ---- ##

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

$fields['billing']['billing_postcode']['class'] = array('form-row-first');
$fields['billing']['billing_city']['class'] = array('form-row-last');

## ---- RETURN THE BILLING FIELDS CUSTOMIZED ---- ##

return $fields;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


Before WooCommerce 3

I am not completely sure, but you there are some things that you can't do like merging billing fields with account fields. If you want to do that is going to be much more complicated than what you are trying to do here. In that case you will need to rewrite/create some checkout templates…

Another thing is that billing_email and billing_phone are sharing the same line together with 'class' => 'form-row-first' and 'class' => 'form-row-last'. When not this class is define 'class' => 'form-row-wide'… So you are going to need overriding these 'class' too.

After that you dont need to use 'woocommerce_checkout_init' hook…

You can still use 'woocommerce_checkout_fields'.

Also you can merge all of them in one function this way:

/*
* Creating, overriding and reordering custom fields.
*/
add_filter( "woocommerce_checkout_fields", "custom_override_checkout_fields", 11, 1 );
function custom_override_checkout_fields( $fields ) {

// Creating 'billing_email2' field
$fields['billing']['billing_email2'] = array(
'type' => 'text',
'label' => __( 'Confirm Email Address', 'woocommerce' ),
'placeholder' => _x( 'Confirm Email Address', 'placeholder', 'woocommerce' ),
'required' => true,
'class' => array('form-row-last'),
'clear' => true
);

// =======> I don't really know if you need this one <========
// it already exist (see in first reference link at bottom).

// Creating 'account_password2' field
if ( get_option( 'woocommerce_registration_generate_password' ) == 'no' ) {
$fields['account']['account_password2'] = array(
'type' => 'password',
'label' => __( 'Confirm password', 'woocommerce' ),
'placeholder' => _x( 'Confirm Password', 'placeholder', 'woocommerce' ),
'required' => true,
'class' => array('form-row-wide') //,
// 'clear' => true
);
}

// Overriding existing billing_phone field 'class' property
$fields['billing']['billing_phone']['class'] = array('form-row-wide');

// Reordering billing fields
$order = array(
"billing_first_name",
"billing_last_name",
"billing_email",
"billing_email2",
"billing_phone",
"billing_company",
"billing_address_1",
"billing_address_2",
"billing_postcode",
"billing_country"
);

foreach($order as $field)
{
$ordered_fields[$field] = $fields["billing"][$field];
}

$fields["billing"] = $ordered_fields;

return $fields;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

As I have said before, I think that you can't merge billing fields with account fields.

As 'account_password2' already exist if you refer to official documentation (see below in first reference link), you may not need to create it. You will have to test this and to fine tune it. But this is the way to do it.


References:

  • Official: Customizing checkout fields using actions and filters
  • How to reorder billing fields in WooCommerce Checkout template?

Reorder Woocommerce checkout fields

The method you are using no longer works (since the WooCommerce 3.0.4 update - link to github issue here). It's not exactly a bug, but rather a change of spec.

To fix this, you simply need to adjust the priority of each of the fields to fit the order that you want.

add_filter("woocommerce_checkout_fields", "custom_override_checkout_fields", 1);
function custom_override_checkout_fields($fields) {
$fields['billing']['billing_first_name']['priority'] = 1;
$fields['billing']['billing_last_name']['priority'] = 2;
$fields['billing']['billing_company']['priority'] = 3;
$fields['billing']['billing_country']['priority'] = 4;
$fields['billing']['billing_state']['priority'] = 5;
$fields['billing']['billing_address_1']['priority'] = 6;
$fields['billing']['billing_address_2']['priority'] = 7;
$fields['billing']['billing_city']['priority'] = 8;
$fields['billing']['billing_postcode']['priority'] = 9;
$fields['billing']['billing_email']['priority'] = 10;
$fields['billing']['billing_phone']['priority'] = 11;
return $fields;
}

add_filter( 'woocommerce_default_address_fields', 'custom_override_default_locale_fields' );
function custom_override_default_locale_fields( $fields ) {
$fields['state']['priority'] = 5;
$fields['address_1']['priority'] = 6;
$fields['address_2']['priority'] = 7;
return $fields;
}

Please note that it's not the line in code that adjusts the placement in the order, but the priority assigned to the field. In this case, I changed the ['billing_state'] priority to 5 which is (in this example) after ['billing_country'] and before ['billing_address_1'].


EDIT:

As per the comments, this wasn't working for some reason (it worked on my first test WooCommerce installation, but I managed to get it to fail after changing the store location).

After some digging, I found that the default locale settings get applied on top of the override (not sure how else to explain this, but bear with me).

I managed to get an install running where the above code was not working, and managed to fix it by adding the following code as well:

add_filter( 'woocommerce_default_address_fields', 'custom_override_default_locale_fields' );
function custom_override_default_locale_fields( $fields ) {
$fields['state']['priority'] = 5;
$fields['address_1']['priority'] = 6;
$fields['address_2']['priority'] = 7;
return $fields;
}

I have added the extra snippet to the first code block to validate the entire block.

How to reorder additional fields on checkout page in WooCommerce

If you want to show your custom field first, and then the order notes.

You can either use:

// Add 'delivery time' field before 'order comments'
function filter_woocommerce_checkout_fields( $fields ) {
// Get 'order comments' field
$order_comments = $fields['order']['order_comments'];

// Unset 'order comments' field
unset( $fields['order']['order_comments'] );

// Add 'delivery time' field
$fields['order']['delivery_time'] = array(
'label' => __( 'Delivery time', 'woocommerce' ),
'required' => true,
'type' => 'text',
'class' => array( 'form-row-wide' ),
);

// Add 'order comments' field
$fields['order']['order_comments'] = $order_comments;

return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'filter_woocommerce_checkout_fields', 10, 1 );

OR use the woocommerce_before_order_notes action hook

function action_woocommerce_before_order_notes( $checkout ) {       
// Add field
woocommerce_form_field( 'delivery_time', array(
'type' => 'text',
'class' => array( 'form-row form-row-wide' ),
'label' => __( 'Delivery time', 'woocommerce' ),
'required' => true,
), $checkout->get_value( 'delivery_time' ) );
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );

Change the order from additional checkout fields in WooCommerce checkout manager

WooCommerce checkout manager plugin doesn't allow to reorder additional fields and it save that data in some of his option settings.

So the way is to alter the plugin settings just once.

To run the following code, just browse any page of your web site.

You will run it just once and then remove it.

The code:

function wccs_change_fields_order(){
$wccs_settings = get_option( 'wccs_settings' );

// Get the array of additional fields
$additional_fields = $wccs_settings['buttons'];

// SETTINGS: Here set your 2 product attribute Names
$format = 'Format';
$rp_carton = 'Rolls per Carton';

// FIRST Loop Get the array key for 'Rolls per Carton' field label
foreach( $additional_fields as $key => $field ){
if( $field['label'] == $rp_carton )
$key_rp_carton = $key;
}

// Save 'Rolls per Carton' data field in a variable
$field_rp_carton = $additional_fields[$key_rp_carton];

// Remove 'Rolls per Carton' data field from the fields array
unset($additional_fields[$key_rp_carton]);

// Initializing variables
$new_additional_fields = array();
$sorting_index = 1;

// SECOND Loop reordering fields
foreach( $additional_fields as $key => $field ){
// Update "order" argument
$field['order'] = $sorting_index;

// Add the current field to a new array
$new_additional_fields[] = $field;

$sorting_index++; // Increment sorting index

// When we reach 'Format' data field
if( $field['label'] == $format ){
// Set a new position to 'Rolls per Carton' attribute
$field_rp_carton['order'] = $sorting_index;

// Add 'Rolls per Carton' field data in the new array
$new_additional_fields[] = $field_rp_carton;

$sorting_index++; // Increment sorting index
}
}
// Set back the reordered additional fields in the main array
$wccs_settings['buttons'] = $new_additional_fields;

// Update the new changed options (Save)
update_option( 'wccs_settings', $wccs_settings, 'yes' );
}

wccs_change_fields_order();

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

add a custom checkout billing field under the last name in WooCommerce

You need to use the "priority" argument, which will allow you to set your field in the correct location (after the first and last name fields).

Normally "billing first name" has a 10 as priority and "billing last name 20 as priority. Then comes the "billing company" that has 30 as priority… So for your custom billing field use a priority of 25 (in between).

There is a little mistake in your code for the placeholder where you should replace _x() function by __().

Your code is going to be:

add_filter('woocommerce_checkout_fields', 'custom_woocommerce_billing_fields');
function custom_woocommerce_billing_fields( $fields )
{
$fields['billing']['billing_options'] = array(
'label' => __('תאריך לידה', 'woocommerce'), // Add custom field label
'placeholder' => __('תאריך לידה', 'woocommerce'), // Add custom field placeholder
'required' => true, // if field is required or not
'clear' => false, // add clear or not
'type' => 'date', // add field type
'class' => array('my-css'), // add class name
'priority' => 25, // Priority sorting option
);

return $fields;
}

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

If you want this field after the billing company, you will use a priority of 35 instead.

Related: Reordering checkout fields in WooCommerce 3

Sorting priority for specific Woocommerce checkout fields depending on country

Using available filter hook you can make that change without overriding core files…

The first change is made with this hook (for "IT" country code):

add_filter('woocommerce_get_country_locale', 'custom__country_locale', 30, 1 );
function wps_select_order_meta_keys( $locale ) {
$locale['IT']['postcode']['priority'] = 91;
return $locale;
}

For the second change you need also to change the class. It's the same code that you already have in the answer to your other question, but without this line to be removed:

if( ! is_account_page() ) return $fields;

The code is:

add_filter(  'woocommerce_billing_fields', 'custom_billing_fields', 20, 1 );
function custom_billing_fields( $fields ) {

## ---- 1. 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;
}

So if you remove if( ! is_account_page() ) return $fields; from the code in my other answer, it will work also on checkout page (as as already indicated)…

So you can use (for both account and checkout pages):

add_filter(  'woocommerce_default_address_fields', 'custom_default_address_fields', 20, 1 );
function custom_default_address_fields( $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;
}

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



Related Topics



Leave a reply



Submit