I\'m adding WooCommerce custom checkout fields in a Storefront child theme functions.php
file.
They have a \"required\" attribute.
The ai
**/* If You Have Created Your Custom Field at the checkout page */**
add_action( 'woocommerce_after_checkout_validation', 'shipping_time_optionss', 9999, 2);
function shipping_time_optionss( $fields, $errors ){
// if any validation errors
if ( empty( $_POST['woo_shipping_time'] ) ) {
$errors->add( 'woocommerce_password_error', __( 'Please Select Shipping Time Option.' ) );
} `enter code here`
}
As you can read in woocommerce_before_checkout_form
hook, it's before checkout form (so outside the checkout form). For this reason this custom field can't work in this hook.
You can use instead woocommerce_checkout_update_order_meta
action hook, making some little changes in your code as there is no $checkout argument available in it.
This will display the field "at the top of the page, before the billing fields"…
So your complete code should be now:
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_checkout_before_customer_details', 'my_custom_checkout_fields' );
function my_custom_checkout_fields() {
echo '<div id="my_custom_checkout_field" class="col4-set"><h2>' . __('name') . '</h2>';
woocommerce_form_field( 'developer_name', array(
'type' => 'text',
'class' => array('developer_name-class form-row form-row-first'),
'label' => __('name'),
'placeholder' => __('fill in your name'),
'required' => true,
), WC()->checkout->get_value( 'developer_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['developer_name'] )
wc_add_notice( __( 'Please fill in your name.' ), 'error' );
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta', 10, 1 );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['developer_name'] ) ) {
update_post_meta( $order_id, 'Developer name', sanitize_text_field( $_POST['developer_name'] ) );
}
}
// Display the custom-field in orders view
add_action( 'woocommerce_order_details_after_customer_details', 'display_my_custom_field_in_orde_details', 10, 1 );
function display_my_custom_field_in_orde_details( $order ) {
$developer_name = get_post_meta( $order->get_id(), 'Developer name', true );
if ( ! empty( $developer_name ) ):
?>
<table class="woocommerce-table woocommerce-table--customer-details shop_table customer_details">
<tbody><tr>
<th>Developer name:</th>
<td><?php echo $developer_name; ?></td>
</tr></tbody>
</table>
<?php
endif;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for WooCommerce version 3.0+
You try this code. Tested Ok
add_action( 'woocommerce_billing_fields', 'my_custom_checkout_fields' );
function my_custom_checkout_fields( $fields ) {
$fields['billing_developer_name'] = array(
'label' => __('Developer name', 'woocommerce'),
'placeholder' => _x('Developer name', 'placeholder', 'woocommerce'),
'required' => TRUE,
'clear' => false,
'type' => 'text',
'class' => array('my-css')
);
return $fields;
}
You can arrange it with this snippet
add_filter("woocommerce_checkout_fields", "order_fields");
function order_fields($fields) {
$order = array(
"billing_developer_name",
"billing_first_name",
"billing_last_name",
"billing_company",
"billing_address_1",
"billing_address_2",
"billing_postcode",
"billing_country",
"billing_email",
"billing_phone"
);
foreach($order as $field)
{
$ordered_fields[$field] = $fields["billing"][$field];
}
$fields["billing"] = $ordered_fields;
return $fields;
}
See screenshot