How to add custom fields to WooCommerce registration form

23,013

Solution 1

I think you have overwrite woocommerce/templates/myaccount/form-login.php template, and by doing that you have managed to show the billing_first_name and billing_last_name but you forget to use woocommerce_created_customer hook which is needed to save those data into your database.

What I'll suggest is that you keep the template as it is and add those field through function.php

Here is the code to add custom fields in WooCommerce registration form:

/**
 * To add WooCommerce registration form custom fields.
 */

function text_domain_woo_reg_form_fields() {
    ?>
    <p class="form-row form-row-first">
        <label for="billing_first_name"><?php _e('First name', 'text_domain'); ?><span class="required">*</span></label>
        <input type="text" class="input-text" name="billing_first_name" id="billing_first_name" value="<?php if (!empty($_POST['billing_first_name'])) esc_attr_e($_POST['billing_first_name']); ?>" />
    </p>
    <p class="form-row form-row-last">
        <label for="billing_last_name"><?php _e('Last name', 'text_domain'); ?><span class="required">*</span></label>
        <input type="text" class="input-text" name="billing_last_name" id="billing_last_name" value="<?php if (!empty($_POST['billing_last_name'])) esc_attr_e($_POST['billing_last_name']); ?>" />
    </p>
    <div class="clear"></div>
    <?php
}

add_action('woocommerce_register_form_start', 'text_domain_woo_reg_form_fields');

Coming to your second part of your question on validation it is totally optional and depends on your business logic that what you want, in general most of the site has First Name and the Last Name required but again it totally depends upon you, If you don't want to validate this then remove <span class="required">*</span> from above code and skip this section.

/**
 * To validate WooCommerce registration form custom fields.
 */
function text_domain_woo_validate_reg_form_fields($username, $email, $validation_errors) {
    if (isset($_POST['billing_first_name']) && empty($_POST['billing_first_name'])) {
        $validation_errors->add('billing_first_name_error', __('<strong>Error</strong>: First name is required!', 'text_domain'));
    }

    if (isset($_POST['billing_last_name']) && empty($_POST['billing_last_name'])) {
        $validation_errors->add('billing_last_name_error', __('<strong>Error</strong>: Last name is required!.', 'text_domain'));
    }
    return $validation_errors;
}

add_action('woocommerce_register_post', 'text_domain_woo_validate_reg_form_fields', 10, 3);

Now this is a main part and this what you was had missed, below code is needed to save the custom data:

/**
 * To save WooCommerce registration form custom fields.
 */
function text_domain_woo_save_reg_form_fields($customer_id) {
    //First name field
    if (isset($_POST['billing_first_name'])) {
        update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
        update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
    }
    //Last name field
    if (isset($_POST['billing_last_name'])) {
        update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
        update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
    }
}

add_action('woocommerce_created_customer', 'text_domain_woo_save_reg_form_fields');

All the above code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
The code is tested and fully functional.
Hope this helps!

Solution 2

<?php
/**
 * Add new register fields for WooCommerce registration
 * To add WooCommerce registration form custom fields.
 */
add_action( 'woocommerce_register_form', 'misha_add_register_form_field' );
 
function misha_add_register_form_field(){
 
    woocommerce_form_field(
        'billing_first_name',
        array(
            'type'        => 'text',
            'required'    => true, // just adds an "*"
            'label'       => 'First name'
        ),
        ( isset($_POST['billing_first_name']) ? $_POST['billing_first_name'] : '' )
    );
    woocommerce_form_field(
        'billing_last_name',
        array(
            'type'        => 'text',
            'required'    => true, // just adds an "*"
            'label'       => 'Last name'
        ),
        ( isset($_POST['billing_last_name']) ? $_POST['billing_last_name'] : '' )
    );
    woocommerce_form_field(
        'billing_phone',
        array(
            'type'        => 'tel',
            'required'    => true, // just adds an "*"
            'label'       => 'Phone'
        ),
        ( isset($_POST['billing_phone']) ? $_POST['billing_phone'] : '' )
    );
 
}
/**
 * To validate WooCommerce registration form custom fields.
 */
add_action( 'woocommerce_register_post', 'misha_validate_fields', 10, 3 );
 
function misha_validate_fields( $username, $email, $errors ) {
 
    if ( empty( $_POST['billing_first_name'] ) ) {
        $errors->add( 'billing_first_name_error', 'First name is required!' );
    }
    if ( empty( $_POST['billing_last_name'] ) ) {
        $errors->add( 'billing_last_name_error', 'Last name is required!' );
    }
    if ( empty( $_POST['billing_phone'] ) ) {
        $errors->add( 'billing_phone_error', 'Phone is required!' );
    }
 
}
/**
 * To save WooCommerce registration form custom fields.
 */
add_action( 'woocommerce_created_customer', 'misha_save_register_fields' );
 
function misha_save_register_fields( $customer_id ){
   //First name field
    if ( isset( $_POST['billing_first_name'] ) ) {
        //update_user_meta( $customer_id, 'country_to_visit', wc_clean( $_POST['country_to_visit'] ) );
        update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
        update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
    }
    //Last name field
    if (isset($_POST['billing_last_name'])) {
        update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
        update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
    }
    // WooCommerce billing phone
    if ( isset( $_POST['billing_phone'] ) ) {
        update_user_meta( $customer_id, 'billing_phone', sanitize_text_field( $_POST['billing_phone'] ) );
    }
 
}
?>

Solution 3

Adding Woocommerce registration form custom fields using filter hook woocommerce_forms_field and saving data with nonce verification.

/**
 * Adding more fields to Woocommerce Registration form and My account page
 */

function how_woocommerce_registration_form_fields() {
    return apply_filters( 'woocommerce_forms_field', array(
            'billing_company' => array(
                    'type'        => 'text',
                    'label'       => __( 'Company Name', ' how' ),
                    'required'    => false,
            ),
            'how_user_job_title' => array(
                'type'        => 'text',
                'label'       => __( 'Job Title', ' how' ),
                'required'    => false,
            ),
            'how_user_industry'     => array(
                'type'    => 'select',
                'label'   => __( 'Industry', 'how' ),
                'options' => array(
                        ''                                      => __( 'Select an Industry', 'how' ),
                        'Lending'                       => __( 'Lending', 'how' ),
                        'Real Estate'               => __( 'Real Estate', 'how' ),
                        'Investment'                => __( 'Investment', 'how' ),
                        'Servicing'                     => __( 'Servicing', 'how' ),
                        'Other'                             => __( 'Other', 'how' ),
                        'Mortgage Servicing'    => __( 'Mortgage Servicing', 'how' ),
                        'Mortgage Lending'      => __( 'Mortgage Lending', 'how' ),
                )
            )
    ) );
}
function how_woocommerce_edit_registration_form() {
    $fields = how_woocommerce_registration_form_fields();
    foreach ( $fields as $key => $field_args ) {
            woocommerce_form_field( $key, $field_args );
    }
}
add_action( 'woocommerce_register_form', 'how_woocommerce_edit_registration_form', 15 );

/**
 * Save registration form custom fields
 */

function wooc_save_extra_register_fields( $customer_id ) {
    if( wp_verify_nonce( sanitize_text_field( $_REQUEST['woocommerce-register-nonce'] ), 'woocommerce-register' ) ) {
        if ( isset( $_POST['billing_company'] ) ) {
            update_user_meta( $customer_id, 'billing_company', sanitize_text_field( $_POST['billing_company'] ) );
            update_user_meta( $customer_id, 'shipping_company', sanitize_text_field( $_POST['billing_company'] ) );
        }
        if ( isset( $_POST['how_user_job_title'] ) ) {
            update_user_meta( $customer_id, 'how_user_job_title', sanitize_text_field( $_POST['how_user_job_title'] ) );
        }
        if ( isset( $_POST['how_user_industry'] ) ) {
            update_user_meta( $customer_id, 'how_user_industry', sanitize_text_field( $_POST['how_user_industry'] ) );
        }
    }
}
add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' );
Share:
23,013
Admin
Author by

Admin

Updated on September 02, 2021

Comments

  • Admin
    Admin over 2 years

    I have seen similar questions but couldn't find a solution for me.

    I am trying to add custom fields to WooCommerce registration form, specifically first and last name field. I have managed to create these fields but the information entered does not pass over to the Account Details page when the user has logged in. Other tutorials have mentioned validating the fields but I am not sure is it relevant to me or not. I am working on a Wordpress child theme.

    Please visit to codepad .org to view the code. I tried to paste the code here by using the code sample option but it doesn't work properly.

    Hope I have explained myself clearly. If not please let me know and I will clarify.

  • Soeurng Sar
    Soeurng Sar over 5 years
    I see many solutions response to this question is always using existing fields like billing_first_name or billing_last_name. The question is asking about custom fields for example membership_id or something else that not related to existing fields. Is it possible to add by hook?
  • Raunak Gupta
    Raunak Gupta over 5 years
    @SoeurngSar: it work for all the fields custom or predefined.
  • Steve Moretz
    Steve Moretz about 3 years
    Thanks was really looking for this