WooCommerce Registration Help

So I have this code for the WooCommerce registration that adds their billing address to the registration form and I cannot figure out two items:
1- For the billing country- When you select a country outside of the United States such as Canada, the state/province does not show. It only shows the USA States.
2-I cannot make the Country and States search able with text like on the real WooCommerce billing.
3- I cannot figure out how to add a checkbox with 'I agree to Terms and Conditions' and may it required.

if(!is_admin())
{
// Function to check starting char of a string
function startsWith($haystack, $needle)
{
return $needle === '' || strpos($haystack, $needle) === 0;
}
// Custom function to display the Billing Address form to registration page
function my_custom_function()
{
global $woocommerce;
$checkout = $woocommerce->checkout();
?>
<h3><?php _e( 'Billing Information', 'woocommerce' ); ?></h3>
<?php
foreach ($checkout->checkout_fields['billing'] as $key => $field) :
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
endforeach;
}
add_action('register_form','my_custom_function');

// Custom function to save Usermeta or Billing Address of registered user
function save_address($user_id)
{
global $woocommerce;
$address = $_POST;
foreach ($address as $key => $field) :
if(startsWith($key,'billing_'))
{
// Condition to add firstname and last name to user meta table
if($key == 'billing_first_name' || $key == 'billing_last_name')
{
$new_key = explode('billing_',$key);
update_user_meta( $user_id, $new_key[1], $_POST[$key] );
}
update_user_meta( $user_id, $key, $_POST[$key] );
}
endforeach;

}
add_action('woocommerce_created_customer','save_address');

// Registration page billing address form Validation
function custom_validation()
{
global $woocommerce;
$address = $_POST;
foreach ($address as $key => $field) :
// Validation: Required fields
if(startsWith($key,'billing_'))
{
if($key == 'billing_country' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please select a country.', 

'woocommerce' ) );
}
if($key == 'billing_first_name' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter first name.', 

'woocommerce' ) );
}
if($key == 'billing_last_name' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter last name.', 

'woocommerce' ) );
}
if($key == 'billing_address_1' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter address.', 

'woocommerce' ) );
}
if($key == 'billing_city' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter city.', 

'woocommerce' ) );
}
if($key == 'billing_state' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter state.', 

'woocommerce' ) );
}
if($key == 'billing_postcode' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter a postcode.', 

'woocommerce' ) );
}
if($key == 'billing_email' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter billing email 

address.', 'woocommerce' ) );
}
if($key == 'billing_phone' && $field == '')
{
$woocommerce->add_error( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter phone number.', 

'woocommerce' ) );
}

}
endforeach;
}
add_action('register_post','custom_validation');
}
  • Kasia Swiderska

    Hello Brandi,

    Those fields are not working because that script only adds fields but to work those fields need JS scripts.
    I'm not familiar with WooCommerce and I found only this thread https://wordpress.org/support/topic/add-extra-fields-to-my-account-page/ (there is no action there to enqueue that on specific page) where you have link to script that is required.
    You could enqueue that script using this tutorial http://websitetutorials.grafix.gr/e-shop/woocommerce/override-woocommerce-frontend-scripts/ - but don't deregister scripts - only add your own.
    You will need also this script https://github.com/woocommerce/woocommerce/blob/master/assets/js/frontend/address-i18n.js

    Other, ugly solution is to change WooCommerce code in file /wp-content/plugins/woocommerce/includes/class-wc-frontend-scripts.php in line 182 where you can add line

    self::enqueue_script( 'wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery', 'wc-country-select', 'wc-address-i18n' ) );

    and this will make form work properly on account page.

    3- I cannot figure out how to add a checkbox with 'I agree to Terms and Conditions' and may it required.

    Please take at this plugin https://srd.wordpress.org/plugins/agreeable/ - it has option to add those into WooCommerce registration form.

    kind regards,
    Kasia

  • Brandi

    After what seems like endless hours of creating, researching, editing and testing, here is the code that is currently working for me for creating a WooCommerce registration form with the billing address. (Wish I was better at this as for an expert it would probably be quick and easy lol)
    Hopefully it can be useful for someone else as well.
    Copy and Paste in your child themes functions file and hopefully it will work for you too.

    //custom code corrections for WooCommerce Custom Registration
    
        // Function to check starting char of a string
        function startsWith($haystack, $needle)
        {
            return $needle === '' || strpos($haystack, $needle) === 0;
        }
    
        add_action( 'woocommerce_checkout_init', 'woocommerce_countries_states', 10, 1 );
        function woocommerce_countries_states( $checkout ) {
            global $woocommerce;
            $countries_obj   = new WC_Countries();
            $countries   = $countries_obj->__get('countries');
            $default_country = $countries_obj->get_base_country();
            $default_county_states = $countries_obj->get_states( $default_country );
    
            $checkout->checkout_fields['account']['billing_country'] = array(
                'type'              => 'select',
                'label'             => __( 'Default Contries', 'woocommerce' ),
                'required'          => true,
                'options'    => $countries
            );
    
            $checkout->checkout_fields['account']['billing_country'] = array(
                'type'              => 'select',
                'label'             => __( 'Default Contries', 'woocommerce' ),
                'required'          => true,
                 'options'    => $default_county_states
            );
        }
    
        add_action( 'register_form', 'woocommerce_reg_extra', 15 );
        //add_action( 'woocommerce_register_form', 'woocommerce_reg_extra');
    
        function woocommerce_reg_extra() {
            global $woocommerce;
            $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
            $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/';
            $frontend_script_path = $assets_path . 'js/frontend/';
            wp_enqueue_script( 'wc-country-select', $frontend_script_path . 'country-select' . $suffix . '.js' );
    
            $checkout = $woocommerce->checkout();
            ?>
            <h3><?php _e( 'Billing Information', 'woocommerce' ); ?></h3>
            <?php
            foreach ($checkout->checkout_fields['billing'] as $key => $field) :
            woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
            endforeach;
            ?>
    
            <div class = "terms_checkbox">
     			<input type="checkbox" name="terms_agree" value="1" />
     			<a href = "/terms">I agree to Terms and Conditions</a>
            </div>
            <?php
        }
    
        // Custom function to save Usermeta or Billing Address of registered user
        function save_address($user_id)
        {
            global $woocommerce;
            $address = $_POST;
            foreach ($address as $key => $field) :
            if(startsWith($key,'billing_'))
            {
            // Condition to add firstname and last name to user meta table
            if($key == 'billing_first_name' || $key == 'billing_last_name')
            {
            $new_key = explode('billing_',$key);
            update_user_meta( $user_id, $new_key[1], $_POST[$key] );
            }
            update_user_meta( $user_id, $key, $_POST[$key] );
            }
            endforeach;
    
        }
        add_action('woocommerce_created_customer','save_address', 10, 3);
    
        // Registration page billing address form Validation
    
        function validate_extra_wp_register_fields( $errors, $sanitized_user_login, $user_email )
        {
            global $woocommerce;
    
            /*     	if ( empty($_POST['billing_country'])  )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please select a country.', 'woocommerce' ) );
            }
    
        	if ( empty($_POST['billing_first_name']) )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter first name.', 'woocommerce' ) );
            }
    
        	if ( empty($_POST['billing_last_name']) )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter last name.', 'woocommerce' ) );
            }
            if ( empty($_POST['billing_address_1']) )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter address.', 'woocommerce' ) );
            }
        	if ( empty($_POST['billing_city']) )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter city.', 'woocommerce' ) );
            }
    
        	if ( empty($_POST['billing_state'])  )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter state.', 'woocommerce' ) );
            }
    
        	if ( empty($_POST['billing_postcode'])  )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter a postcode.', 'woocommerce' ) );
            }
    
        	if ( empty($_POST['billing_email']) )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter billing email address.', 'woocommerce' ) );
            }
        	if ( empty($_POST['billing_phone'])  )
            {
            	$errors->add( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Please enter phone number.', 'woocommerce' ) );
            }
        	if ( empty($_POST['terms_agree'])  )
            {
            	$errors->add( 'You must agree to our Terms and Conditions');
            }
            */
            return $errors;
        }
    
    add_filter('registration_errors','validate_extra_wp_register_fields', 10, 3);
    add_action( 'woocommerce_register_post', 'validate_extra_register_fields', 10, 3 );
    
    function validate_extra_register_fields( $username, $email, $validation_errors )
    {
    
    	if ( empty($_POST['billing_country'])  )
        {
        	$validation_errors->add( 'country_error', __( '<strong>Error</strong>: First select a country.', 'woocommerce' ) );
        }
    
    	if ( empty($_POST['billing_first_name']) )
        {
        	 $validation_errors->add( 'first_name_error', __( '<strong>Error</strong>: Please enter first name.', 'woocommerce' ) );
        }
    
    	if ( empty($_POST['billing_last_name']) )
        {
        	$validation_errors->add( 'last_name_error', __( '<strong>Error</strong>: Please enter last name.', 'woocommerce' ) );
        }
        if ( empty($_POST['billing_address_1']) )
        {
        	$validation_errors->add( 'address1_error', __( '<strong>Error</strong>: Please enter address.', 'woocommerce' ) );
        }
    	if ( empty($_POST['billing_city']) )
        {
        	$validation_errors->add( 'address2_error', __( '<strong>Error</strong>: Please enter city.', 'woocommerce' ) );
        }
    
    	if ( empty($_POST['billing_state'])  )
        {
        	$validation_errors->add( 'state_error', __( '<strong>Error</strong>: Please select or enter a state.', 'woocommerce' ) );
        }
    
    	if ( empty($_POST['billing_postcode'])  )
        {
        	$validation_errors->add( 'postcode_error', __( '<strong>Error</strong>: Please enter a postcode.', 'woocommerce' ) );
        }
    
    	if ( empty($_POST['billing_email']) )
        {
        	$validation_errors->add( 'email_error', __( '<strong>Error</strong>: Please enter email.', 'woocommerce' ) );
        }
    	if ( empty($_POST['billing_phone'])  )
        {
        	$validation_errors->add( 'phone_error', __( '<strong>Error</strong>: Please enter a phone number.', 'woocommerce' ) );
        }
    	if ( empty($_POST['terms_agree'])  )
        {
        	$validation_errors->add( 'terms_error', __( '<strong>Error</strong>: Please agree to our terms and conditions to use this service.', 'woocommerce' ) );
        }
    }