Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Add select-options field in Woocommerce checkout Billing Fields. WordPress

  • SOLVED

I want to create a custom SELECT field in Billing checkout page in Woocommerce. (As stated in this article)
http://docs.woothemes.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
I follow the article and succeed in showing up the SELECT Field.

But the data seems not to be saved in database and the value is not chosen for the second time. What I want is: when a registered user go to checkout for the second time, the value is selected/chosen as he/she selected for the first time. Just like the select state and city.
For example, add Gender consists of Male and Female. When a user select Male for the first time, then the second time he goes to checkout the Gender will be selected "Male".

How do I do that?

Answers (1)

2015-05-20

Reigel Gallarde answers:

3 things for this to work...

1. you have to add extra fields.
2. you have to save the extra fields for the current user.
3. get the saved value.

add_filter( 'woocommerce_checkout_fields', 'add_extra_fields' );
function add_extra_fields($checkout_fields){
$checkout_fields['billing']['user_gender'] = array(
'type' => 'select',
'options' => array( 'male' => 'Male', 'female' => 'Female'),
'label' => __('Gender', 'woocommerce'),
);
return $checkout_fields;
}
add_action( 'woocommerce_checkout_order_processed', 'save_extra_fields', 20, 2 );
function save_extra_fields($order_id, $posted) {
if (isset($posted['user_gender'])) {
$order = wc_get_order($order_id);
update_user_meta($order->get_user_id(), 'user_gender', $posted['user_gender']);
}
}

add_filter( 'default_checkout_user_gender', 'checkout_user_gender',10,2 );
function checkout_user_gender($value,$input) {
if ( is_user_logged_in()){
$current_user = wp_get_current_user();
$value = get_user_meta( $current_user->ID, $input, true );
}
return $value;
}


rprabowo comments:

It adds the select field in the checkout, but the selected value is not selected when the user checks out for the second time.

Is it related to CLASS-WC-COUNTRIES.PHP in folder Includes? what does this function do get_default_address_fields() ?


Reigel Gallarde comments:

do you have a test site? I'm pretty sure this code works.

It might be that I did not get the right hook for what you wanted on the saving part..
I've used woocommerce_checkout_order_processed, meaning this happens if a user has sent the order..

it is not related to CLASS-WC-COUNTRIES.PHP


Reigel Gallarde comments:

also, the user needs to be logged in for this to work...


rprabowo comments:

Also you need to know that I add these codes to my function.php. This code brings All billing fields to the registration process.

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 Address', '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( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please select a country.', 'woocommerce' ) );

}

if($key == 'billing_first_name' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter first name.', 'woocommerce' ) );

}

if($key == 'billing_last_name' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter last name.', 'woocommerce' ) );

}

if($key == 'billing_address_1' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter address.', 'woocommerce' ) );

}

if($key == 'billing_city' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter city.', 'woocommerce' ) );

}

if($key == 'billing_state' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter state.', 'woocommerce' ) );

}

if($key == 'billing_postcode' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter a postcode.', 'woocommerce' ) );

}

if($key == 'billing_email' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter billing email address.', 'woocommerce' ) );

}

if($key == 'billing_phone' && $field == '')

{

$woocommerce->add_error( '' . __( 'ERROR', 'woocommerce' ) . ': ' . __( 'Please enter phone number.', 'woocommerce' ) );

}



}

endforeach;

}

add_action('register_post','custom_validation');

}


rprabowo comments:

You said "I've used woocommerce_checkout_order_processed, meaning this happens if a user has sent the order.". Since I place the billing fields in the registration (the user submit that Gender in the registration Not after submit an order), maybe the hooks is different. Maybe you can change the hooks for a user submit that in the Edit Billing Address. What is the hooks for Edit Billing Address?


Reigel Gallarde comments:

you can change the hook to woocommerce_created_customer


Reigel Gallarde comments:

but it would be something like this...

function wooc_save_extra_register_fields( $customer_id ) {
if ( isset( $_POST['user_gender'] ) ) {
update_user_meta( $customer_id, 'user_gender', sanitize_text_field( $_POST['user_gender'] ) );
}
}


Reigel Gallarde comments:

add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' );


rprabowo comments:

Great, it works! Thanks Reigel :)