Quantcast
Channel: WooCommerce Docs » Tutorials
Viewing all articles
Browse latest Browse all 7

Tutorial – Customising checkout fields using actions and filters

$
0
0

How are checkout fields loaded into WooCommerce?

The fields for the checkout (billing and shipping) come from the countries class (class-wc-countries.php) and theget_address_fields function- this is so locale settings are applied to the fields letting WooCommerce enable/disable fields based on the users location.

Before returning the fields, WC will run the fields through a filter. This allows them to be edited by third party plugins and themes (and your own custom code).

Billing:

$address_fields = apply_filters('woocommerce_billing_fields', $address_fields);

Shipping:

$address_fields = apply_filters('woocommerce_shipping_fields', $address_fields);

The checkout class adds the loaded fields to its ‘checkout_fields’ array, as well as adding a few other fields like “order notes”.

$this->checkout_fields['billing']    = $woocommerce->countries->get_address_fields( $this->get_value('billing_country'), 'billing_' );
$this->checkout_fields['shipping']   = $woocommerce->countries->get_address_fields( $this->get_value('shipping_country'), 'shipping_' );
$this->checkout_fields['account']    = array(
    'account_username' => array(
        'type' => 'text',
        'label' => __('Account username', 'woocommerce'),
        'placeholder' => _x('Username', 'placeholder', 'woocommerce')
        ),
    'account_password' => array(
        'type' => 'password',
        'label' => __('Account password', 'woocommerce'),
        'placeholder' => _x('Password', 'placeholder', 'woocommerce'),
        'class' => array('form-row-first')
        ),
    'account_password-2' => array(
        'type' => 'password',
        'label' => __('Account password', 'woocommerce'),
        'placeholder' => _x('Password', 'placeholder', 'woocommerce'),
        'class' => array('form-row-last'),
        'label_class' => array('hidden')
        )
    );
$this->checkout_fields['order']  = array(
    'order_comments' => array(
        'type' => 'textarea',
        'class' => array('notes'),
        'label' => __('Order Notes', 'woocommerce'),
        'placeholder' => _x('Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce')
        )
    );

This array is also passed through a filter:

$this->checkout_fields = apply_filters('woocommerce_checkout_fields', $this->checkout_fields);

This means you have full control over checkout fields – you just need to know how to access them!

Lesson 1 – Overriding core fields

Hooking into the  woocommerce_checkout_fields filter will let you override any field. As a demonstration, lets try changing the placeholder on the order_comments fields. Currently its set to:

_x('Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce')

We can change this by adding a simple function to our theme functions.php file:

// Hook in
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 ) {
     $fields['order']['order_comments']['placeholder'] = 'My new placeholder';
     return $fields;
}

Thats it! You can override other parts too, like the labels:

// Hook in
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 ) {
     $fields['order']['order_comments']['placeholder'] = 'My new placeholder';
     $fields['order']['order_comments']['label'] = 'My new label';
     return $fields;
}

You can even remove fields entirely:

// Hook in
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['order']['order_comments']);

     return $fields;
}

Heres a full list of fields in the array passed to woocommerce_checkout_fields:

  • billing
    • billing_first_name
    • billing_last_name
    • billing_company
    • billing_address_1
    • billing_address_2
    • billing_city
    • billing_postcode
    • billing_country
    • billing_state
    • billing_email
    • billing_phone
  • shipping
    • shipping_first_name
    • shipping_last_name
    • shipping_company
    • shipping_address_1
    • shipping_address_2
    • shipping_city
    • shipping_postcode
    • shipping_country
    • shipping_state
  • account
    • account_username
    • account_password
    • account_password-2
  • order
    • order_comments
Each field contains an array of properties:
  • type – type of field (text, textarea, password, select)
  • label – label for the input field
  • placeholder – placeholder for the input
  • class – class for the input
  • required – true or false, whether or not the field is require
  • clear – true or false, applies a clear fix to the field/label
  • label_class – class for the label element
  • options – for select boxes, array of options (key => value pairs)

Lesson 2 – Adding custom shipping and billing fields

Adding fields is done in a simular way to overriding fields. As an example, lets add a new field to the shipping fields – shipping_phone

// Hook in
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 ) {
     $fields['shipping']['shipping_phone'] = array(
        'label'     => __('Phone', 'woocommerce'),
    'placeholder'   => _x('Phone', 'placeholder', 'woocommerce'),
    'required'  => false,
    'class'     => array('form-row-wide'),
    'clear'     => true
     );

     return $fields;
}

It's alive!

Now we have this new field, what do we do with it? We don’t need to do anything! Because we’re defined the field in the checkout_fields array the field will be automatically processed and saved to the order post meta (in this case the field will be _shipping_phone). If you want to add extra validation rules see the checkout class; there are additional hooks in there you can use.

Lesson 3 – Adding a custom special field

We’ve covered adding fields to billing/shipping/checkout fields but what if we want something more custom? Lets add a new field to the checkout, we can add this new field after order notes by hooking into the following:

/**
 * Add the field to the checkout
 **/
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');

function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>';

    woocommerce_form_field( 'my_field_name', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Fill in this field'),
        'placeholder'       => __('Enter something'),
        ), $checkout->get_value( 'my_field_name' ));

    echo '</div>';

}

This will give us:

Next we need to validate the field when the checkout form gets posted. For the sake of this example we’ll make it required:

/**
 * Process the checkout
 **/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    global $woocommerce;

    // Check if set, if its not set add an error.
    if (!$_POST['my_field_name'])
         $woocommerce->add_error( __('Please enter something into this new shiny field.') );
}

This will show an error on the checkout if the field is left blank:

Finally, lets save the new field to the order custom fields using the following code:

/**
 * Update the order meta with field value
 **/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');

function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ($_POST['my_field_name']) update_post_meta( $order_id, 'My Field', esc_attr($_POST['my_field_name']));
}

Sorted! The field will now be saved to the order.

Example – Make phone number not required


Viewing all articles
Browse latest Browse all 7

Trending Articles