Support » Plugin: WooCommerce » Change order of billing fields on checkout page

  • Resolved zerge

    (@zerge)


    I’m using the WC filter to order billing fields, and it worked fine before (WC 3.0.3) updating to WooCommerce 3.0.4

    It seems the filter works fine, but for unknown reasons it revert back on the fly to the default order.

    
    add_filter("woocommerce_checkout_fields", "custom_order_fields");
    
    function custom_order_fields($fields) {
    	$order = array(
    		"billing_email", 
    		"billing_first_name", 
    		"billing_last_name",
    		"billing_phone", 
    		"billing_address_1",  
    		"billing_postcode",
    		"billing_address_2",
    		"billing_country" 
    	);
    
    	foreach($order as $field)
    	{
    		$ordered_fields[$field] = $fields["billing"][$field];
    	}
    
    	$fields["billing"] = $ordered_fields;
    
    	$fields['billing']['billing_address_1']['placeholder'] = '';
    	$fields['billing']['billing_address_2']['placeholder'] = '';
    	$fields['billing']['billing_phone']['placeholder'] = '';
    	$fields['billing']['billing_address_2']['label'] = __( 'City', 'blank' );
    	$fields['billing']['billing_phone']['label'] = __( 'Phone number', 'blank' );
    
    	return $fields;
    }
    

    STEPS TO REPRODUCE THE ISSUE
    WooCommerce 3.0.4 + code above in the functions.php

Viewing 15 replies - 1 through 15 (of 18 total)
  • Plugin Author Mike Jolley

    (@mikejolley)

    Set ‘priority’ on each field. Thats what controls the sorting order (it’s dynamic).

    I am having the same problem. Mike, could you pleae give me one example of how to add the priority? I have minimal knowledge in coding. Thank you!

    @mikejolley

    It works 🙂 Thanks

    @danina84

    For example, add the code:

    
    $fields['billing']['billing_country']['priority'] = 10;
    $fields['billing']['billing_phone']['priority'] = 20;
    
    • This reply was modified 2 years, 2 months ago by  zerge.
    efrc78

    (@efrc78)

    Hi all,

    this works great, but I’m having an issue with address_1 and 2, seems I can’t change the order of them like

    add_filter(“woocommerce_checkout_fields”, “order_fields”);

    function order_fields($fields) {

    $order = array(
    “billing_company”,
    “billing_address_2”,
    “billing_first_name”,
    “billing_last_name”,
    “billing_country”,
    “billing_city”,
    “billing_state”,
    “billing_address_1”,
    “billing_postcode”,
    “billing_phone”,
    “billing_email”

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

    $fields[“billing”] = $ordered_fields;

    $fields[‘billing’][‘billing_company’][‘priority’] = 10;
    $fields[‘billing’][‘billing_address_2’][‘priority’] = 20;
    $fields[‘billing’][‘billing_first_name’][‘priority’] = 30;
    $fields[‘billing’][‘billing_last_name’][‘priority’] = 40;
    $fields[‘billing’][‘billing_country’][‘priority’] = 50;
    $fields[‘billing’][‘billing_city’][‘priority’] = 60;
    $fields[‘billing’][‘billing_state’][‘priority’] = 70;
    $fields[‘billing’][‘billing_address_1’][‘priority’] = 80;
    $fields[‘billing’][‘billing_postcode’][‘priority’] = 90;
    $fields[‘billing’][‘billing_phone’][‘priority’] = 100;
    $fields[‘billing’][‘billing_email’][‘priority’] = 110;

    return $fields;

    }

    The front-end shows:
    “billing_company”,

    “billing_first_name”,
    “billing_last_name”,
    “billing_country”,
    “billing_address_1”, <—
    “billing_address_2”, <—
    “billing_city”,
    “billing_state”,
    “billing_postcode”,
    “billing_phone”,
    “billing_email”

    any idea or fix?

    • This reply was modified 2 years ago by  efrc78.

    I am having a similar problem as the chap above me. Except my priority doesn’t seem to be effecting any of my fields. This is my code

    add_filter("woocommerce_checkout_fields", "custom_order_fields");
    
    function custom_order_fields($fields) {
            $order = array(
            "billing_first_name",
            "billing_last_name",
            "billing_email",
            "billing_phone",
            "billing_country",
            "billing_company",
            "billing_address_1",
            "billing_address_2",
            "billing_city",
            "billing_postcode"
        );
        foreach($order as $field)
        {
            $ordered_fields[$field] = $fields["billing"][$field];
        }
    
        $fields["billing"] = $ordered_fields;
    
        $fields[‘billing’][‘billing_billing_first_name’][‘priority’] = 10;
        $fields[‘billing’][‘billing_billing_last_name’][‘priority’] = 20;
        $fields[‘billing’][‘billing_billing_email’][‘priority’] = 30;
        $fields[‘billing’][‘billing_billing_phone’][‘priority’] = 40;
        $fields[‘billing’][‘billing_billing_country’][‘priority’] = 50;
        $fields[‘billing’][‘billing_billing_company’][‘priority’] = 60;
        $fields[‘billing’][‘billing_billing_address_1’][‘priority’] = 70;
        $fields[‘billing’][‘billing_billing_address_2’][‘priority’] = 80;
        $fields[‘billing’][‘billing_billing_city’][‘priority’] = 90;
        $fields[‘billing’][‘billing_billing_postcode’][‘priority’] = 100;
    
        return $fields;
    
    }

    Anyone? @mikejolley?

    • This reply was modified 1 year, 11 months ago by  davidhb88.
    • This reply was modified 1 year, 11 months ago by  davidhb88.

    @davidhb88 not sure if you solved it but looks like you’ve got a typo:

    $fields[‘billing’][‘billing_billing_first_name’][‘priority’] = 10;

    instead of

    $fields[‘billing’][‘billing_first_name’][‘priority’] = 10;

    For the latest version of Woocommerce (3.2.4) the following method worked.

    Added to child theme functions.php

    add_filter( ‘woocommerce_default_address_fields’, ‘move_checkout_fields_woo_3’ );

    function move_checkout_fields_woo_3( $fields ) {

    // default priorities:
    // ‘first_name’ – 10
    // ‘last_name’ – 20
    // ‘company’ – 30
    // ‘country’ – 40
    // ‘address_1’ – 50
    // ‘address_2’ – 60
    // ‘city’ – 70
    // ‘state’ – 80
    // ‘postcode’ – 90

    // e.g. move ‘company’ above ‘first_name’:
    // just assign priority less than 10
    $fields[‘company’][‘priority’] = 8;

    return $fields;
    }

    (Adapted from: https://businessbloomer.com/woocommerce-move-reorder-fields-checkout-page/)

    • This reply was modified 1 year, 7 months ago by  dalea.

    I needed to reorder both: billing and shipping fields and for some reason changing their priorities in woocommerce_default_address_fields made fields ordered desired way only for shipping fields. Billing fields were displayed in order they are kept in fields array.

    From the other side, reordering fields in array (without changing priorities) using woocommerce_default_address_fields or woocommerce_checkout_fields filter made and effect only on billing fields.

    Eventually I set priorities and reordered fields in array using woocommerce_default_address_fields filter and both group of fields are displayed in desired order.

    I’m just wondering if this is how it should work, or checkout page I’m working on is so highly customized that default WooCommerce scripts are not triggered on specific fields group.

    • This reply was modified 1 year, 7 months ago by  pawelkmpt. Reason: I want follow the topic

    who has found a solution, how to manage fields and their order?

    Eventually I set priorities and reordered fields in array using woocommerce_default_address_fields filter and both group of fields are displayed in desired order.

    I did as mentioned above

    Can you please paste the full code ? I am a rookie & my code is not working to sequence the fields…

    add_filter( ‘woocommerce_default_address_fields’, ‘yourplugin_move_checkout_fields’ );

    function yourplugin_move_checkout_fields( $fields ) {
    // Author: apppresser.com

    // Move these around as necessary. You’ll see we added email first.
    $billing_order = array(
    “billing_email”,
    “billing_first_name”,
    “billing_last_name”,
    “billing_company”,
    “billing_address_1”,
    “billing_address_2”,
    “billing_postcode”,
    “billing_country”,
    “billing_state”,
    “billing_phone”
    );

    // This sets the billing fields in the order above
    foreach($billing_order as $billing_field) {
    $billing_fields[$billing_field] = $fields[“billing”][$billing_field];

    }

    $fields[“billing”] = $billing_fields;
    $fields[‘billing’][‘billing_first_name’][‘priority’] = 10;
    $fields[‘billing’][‘billing_last_name’][‘priority’] = 20;
    $fields[‘billing’][‘billing_email’][‘priority’] = 30;
    $fields[‘billing’][‘billing_phone’][‘priority’] = 40;
    $fields[‘billing’][‘billing_country’][‘priority’] = 50;
    $fields[‘billing’][‘billing_company’][‘priority’] = 60;
    $fields[‘billing’][‘billing_address_1’][‘priority’] = 70;
    $fields[‘billing’][‘billing_address_2’][‘priority’] = 80;
    $fields[‘billing’][‘billing_city’][‘priority’] = 90;
    $fields[‘billing’][‘billing_postcode’][‘priority’] = 100;

    return $fields;
    }

    I used this one & it worked. it son latest woocommerce.

    // Reorder Checkout Fields
    add_filter(‘woocommerce_checkout_fields’,’reorder_woo_fields’);

    function reorder_woo_fields($fields) {
    $fields2[‘billing’][‘billing_email’] = $fields[‘billing’][‘billing_email’];
    $fields2[‘billing’][‘billing_phone’] = $fields[‘billing’][‘billing_phone’];
    $fields2[‘billing’][‘billing_first_name’] = $fields[‘billing’][‘billing_first_name’];
    $fields2[‘billing’][‘billing_last_name’] = $fields[‘billing’][‘billing_last_name’];
    $fields2[‘billing’][‘billing_country’] = $fields[‘billing’][‘billing_country’];
    $fields2[‘billing’][‘billing_address_1’] = $fields[‘billing’][‘billing_address_1’];
    $fields2[‘billing’][‘billing_address_2’] = $fields[‘billing’][‘billing_address_2’];
    $fields2[‘billing’][‘billing_city’] = $fields[‘billing’][‘billing_city’];
    $fields2[‘billing’][‘billing_postcode’] = $fields[‘billing’][‘billing_postcode’];
    $fields2[‘billing’][‘billing_state’] = $fields[‘billing’][‘billing_state’];

    // Add full width Classes and Clears to Adjustments
    $fields2[‘billing’][‘billing_email’] = array(
    ‘label’ => __(‘Email’, ‘woocommerce’),
    ‘required’ => true,
    ‘class’ => array(‘form-row-wide’),
    ‘clear’ => true
    );
    $fields2[‘billing’][‘billing_phone’] = array(
    ‘label’ => __(‘Phone’, ‘woocommerce’),
    ‘required’ => false,
    ‘class’ => array(‘form-row-wide’),
    ‘clear’ => true
    );

    return $fields2;
    }

    I did it like this:

    
    function custom_default_address_fields( $fields ) {
        $fields_order = array( 'company', 'first_name', 'last_name', 'address_1', 'address_2', 'city', 'postcode', 'country', 'state' );
    
        // Set fields priority
        $priority = 10;
    
        foreach ( $fields_order as $key ) {
            if ( ! isset( $fields[ $key ] ) ) {
                continue;
            }
    
            $fields[ $key ]['priority'] = $priority;
            $priority += 10;
        }
    
        // Change fields order
        $fields_ordered = array();
    
        foreach ( $fields_order as $key ) {
            if ( isset( $fields[ $key ] ) ) {
                $fields_ordered[ $key ] = $fields[ $key ];
            }
        }
    
        return $fields_ordered;
    }
    
    add_filter( 'woocommerce_default_address_fields', 'custom_default_address_fields' );
    
    • This reply was modified 1 year, 4 months ago by  pawelkmpt.
    • This reply was modified 1 year, 4 months ago by  pawelkmpt.

    I’ve added custom fields to the billing area.

    add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
    // Our hooked in function - $fields is passed via the filter!
    function custom_override_checkout_fields( $fields ) {
    	//unset($fields['billing']['billing_company']);
    	unset($fields['shipping']['shipping_company']);
    	unset($fields['shipping']['shipping_email']);
    	
      $fields['billing']['billing_attention'] = array(
    																			    'label'     => __('Attention:', 'woocommerce'),
    																			    'placeholder'   => _x('Attention', 'placeholder', 'woocommerce'),
    																			    'required'  => false,
    																			    'class'     => array('form-row-wide'),
    																			    'clear'     => true
    																			     );
    																			     
      $fields['billing']['billing_s2_email'] = array(
    																			    'label'     => __('Secondary Email:', 'woocommerce'),
    																			    'placeholder'   => _x('Secondary Email', 'placeholder', 'woocommerce'),
    																			    'required'  => false,
    																			    'class'     => array('form-row-wide'),
    																			    'clear'     => true
    																			     );																			     
    																			     
      $fields['billing']['billing_customer_po'] = array(
    																			    'label'     => __('Customer PO#:', 'woocommerce'),
    																			    'placeholder'   => _x('Customer PO#', 'placeholder', 'woocommerce'),
    																			    'required'  => false,
    																			    'class'     => array('form-row-wide'),
    																			    'clear'     => true
    																			     );		
    	
    	
    	return $fields;
    }
    

    How can I include these as part of the ordering? I tried your method adding to the $fields_order = array( ‘company’, …..
    But it doesn’t seem to work.

    For everyone struggling with the order of the fields here is something that might help. The checkout fields get passed through a filter called ‘woocommerce_checkout_fields’. I used the filter to order the fields based on their priority, but there are more possibilities using this method:

    
    // Filter will do its magic before the fields are passed to the template.
    add_filter('woocommerce_checkout_fields', function($fields) {
    
    	// Do things with your fields like setting the
    	// priority, label, required, etc.
    	// or removing them
    
    	// Example: Set the priorities straight
    	// Probably not meant for this since priority is something
    	// totally different than order.
    	$fields['billing']['billing_first_name']['priority'] = 0;
    	$fields['billing']['billing_last_name']['priority'] = 5;
    	$fields['billing']['billing_email']['priority'] = 10;
    	$fields['billing']['billing_phone']['priority'] = 15;
    	$fields['billing']['billing_country']['priority'] = 20;
    	$fields['billing']['billing_state']['priority'] = 25;
    	$fields['billing']['billing_address_1']['priority'] = 30;
    	$fields['billing']['billing_address_2']['priority'] = 35;
    	$fields['billing']['billing_postcode']['priority'] = 40;
    	$fields['billing']['billing_city']['priority'] = 45;
    
    	// Sort the fields based on their 'priority'
    	usort($fields['billing'], function($a, $b) {
    		return $a['priority'] <=> $b['priority'];
    	});
    
    	// Send the fields to the function that receives the fields data
    	return $fields;
    }
    

    This works great without having to edit the template at all.

    Conclusion: Just setting the priority does NOT completely change the order. Some Woocommerce sorting problem (or intention) might be in works here.

    • This reply was modified 1 year, 2 months ago by  rlautan. Reason: grammar
Viewing 15 replies - 1 through 15 (of 18 total)
  • The topic ‘Change order of billing fields on checkout page’ is closed to new replies.