I'm trying to put two custom fields at the top of the woocommerce checkout (ideally it was the cart page but I can't find anything online about this being possible)
I've got the two custom fields to appear on the checkout page but with VERY limited php knowledge I've tried to create a drop down menu etc. All seems well on face value. The fields appear on the checkout page BUT whenever I enter info and try to proceed with the order to test if the values show on the thank you pages and on the email, I'm asked to fill in the information in these required fields. For some reason the page isn't recognising the fields are empty
I used this post...https://www.businessbloomer.com/woocommerce-add-custom-checkout-field-php/
but I've had to edit it quite a bit to get to this point. I'm sure there are a lot of errors.
add_action('woocommerce_before_checkout_form', 'custom_add_custom_checkout_fields');
function custom_add_custom_checkout_fields($checkout)
{
echo '<h3>Event Information</h3>';
// Get the current user ID
$user_id = get_current_user_id();
// Fetch user meta data
$saved_event_venue = $current_user->event_venue;
$saved_hall_stand_number = $current_user->hall_stand_number;
woocommerce_form_field('event_venue', array(
'type' => 'select',
'class' => array('form-row-wide'),
'label' => 'Event/Expo & Venue',
'options' => array(
'' => 'Select an option',
'event1' => 'Event 1 Venue',
'event2' => 'Event 2 Venue',
'event3' => 'Event 3 Venue'
// Add more options as needed
),
'required' => true,
'default' => $saved_event_venue,
), $checkout->get_value('event_venue'));
woocommerce_form_field('hall_stand_number', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => 'Hall & Stand Number',
'placeholder' => 'Enter Hall & Stand Number',
'required' => true,
'default' => $saved_hall_stand_number,
), $checkout->get_value('hall_stand_number'));
}
// Validate custom fields
add_action('woocommerce_checkout_process', 'custom_validate_checkout_fields');
function custom_validate_checkout_fields()
{
if (!$_POST['event_venue']) {
wc_add_notice('Please select an Event/Expo & Venue.', 'error');
if (!$_POST['hall_stand_number']) {
wc_add_notice('Please enter the Hall & Stand Number.', 'error');
}
}
}
// Save custom fields to order
add_action('woocommerce_checkout_update_order_meta', 'custom_save_checkout_fields');
function custom_save_checkout_fields($order_id)
{
if ($_POST['event_venue'])
update_post_meta($order_id, '_event_venue', esc_attr($_POST['event_venue']));
if ($_POST['hall_stand_number'])
update_post_meta($order_id, '_hall_stand_number', esc_attr($_POST['hall_stand_number']));
}
// Display custom fields on order received page and order emails
add_action('woocommerce_thankyou', 'custom_new_checkout_field_thankyou');
function custom_new_checkout_field_thankyou($order_id)
{
if (get_post_meta($order_id, 'event_venue', true))
echo '<p><strong>Event/Expo &Venue:</strong> ' . get_post_meta($order_id, '_Event_venue', true) . '</p>';
if (get_post_meta($order_id, 'hall_stand_number ', true))
echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order_id, '_hall_stand_number', true) . '</p>';
}
add_action('woocommerce_admin_order_data_after_billing_address', 'bbloomer_show_new_checkout_field_order');
function custom_new_checkout_field_order($order)
{
$order_id = $order->get_id();
if (get_post_meta($order_id, '_event_venue', true))
echo '<p><strong>Event/Expo - Venue:</strong> ' . get_post_meta($order_id, '_event_venue', true) . '</p>';
if (get_post_meta($order_id, '_hall_stand_number', true))
echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order_id, '_hall_stand_number', true) . '</p>';
}
add_action('woocommerce_email_after_order_table', 'custom_new_checkout_field_emails', 20, 4);
function bbloomer_show_new_checkout_field_emails($order, $sent_to_admin, $plain_text, $email ) {
if (get_post_meta($order->get_id(), '_license_no', true))
echo '<p><strong>Event/Expo - Venue: </strong> ' . get_post_meta($order->get_id(), '_event_venue', true) . '</p>';
if (get_post_meta($order->get_id(), '_hall_stand_number', true))
echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order->get_id(), '_hall_stand_number', true) . '</p>';
}
Updated
The main error is that $current_user
variable is not defined in your first function. Also you can't use woocommerce_before_checkout_form
hook, as it will display your custom checkout fields outside the checkout form, and they will not work.
There are some other mistakes and missing things. Try the following instead:
// Utility function: Get Event venue select field options
function get_event_venue_options() {
// Add more options as needed to the array
return array(
'event1' => __('Event 1 Venue', 'woocommerce'),
'event2' => __('Event 2 Venue', 'woocommerce'),
'event3' => __('Event 3 Venue', 'woocommerce'),
);
}
// Utility function: Get customer selected Event venue data (for display)
function get_customer_event_venue_data( $order ) {
$options = get_event_venue_options(); // Get event venue options
$event_data = []; // Initializing
if ( $event_venue = $order->get_meta('_event_venue') ) {
$event_data[__('Event/Expo & Venue', 'woocommerce')] = $options[$event_venue];
}
if ( $hall_stand_number = $order->get_meta('_hall_stand_number') ) {
$event_data[__('Hall - Stand Number', 'woocommerce')] = $hall_stand_number;
}
return $event_data;
}
// Utility function: Save customer selected Event venue data
function save_customer_event_venue_data( $object, $type = 'order' ) {
$prefix = $type === 'order' ? '_' : '';
if ( isset($_POST['event_venue']) ) {
$object->update_meta_data($prefix.'event_venue', esc_attr($_POST['event_venue']));
}
if ( isset($_POST['hall_stand_number']) ) {
$object->update_meta_data($prefix.'hall_stand_number', sanitize_text_field($_POST['hall_stand_number']));
}
}
// Display the fields in checkout before order notes
add_action( 'woocommerce_before_order_notes', 'display_custom_checkout_fields', 10, 1 );
function display_custom_checkout_fields( $checkout ) {
$event_venue_options = get_event_venue_options();
echo '<div class="event-info">
<h3>' . __('Event Information', 'woocommerce') . '</h3>';
woocommerce_form_field('event_venue', array(
'type' => 'select',
'class' => array('form-row-wide'),
'label' => __('Event/Expo & Venue', 'woocommerce'),
'options' => array_merge( ['' => __('Select an option', 'woocommerce')], $event_venue_options ),
'required' => true,
), WC()->customer->get_meta('event_venue') );
woocommerce_form_field('hall_stand_number', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Hall & Stand Number', 'woocommerce'),
'placeholder' => __('Enter Hall & Stand Number', 'woocommerce'),
'required' => true,
), WC()->customer->get_meta('hall_stand_number') );
echo '</div>';
}
// Validate custom fields
add_action( 'woocommerce_checkout_process', 'validate_custom_checkout_fields' );
function validate_custom_checkout_fields() {
if ( isset($_POST['event_venue']) && empty($_POST['event_venue']) ) {
wc_add_notice('Please select an Event/Expo & Venue.', 'error');
}
if ( isset($_POST['hall_stand_number']) && empty($_POST['hall_stand_number']) ) {
wc_add_notice('Please enter the Hall & Stand Number.', 'error');
}
}
// Save customer event venue data as order metadata and user meta data
add_action( 'woocommerce_checkout_update_customer', 'save_event_venue_data_as_metadata', 10, 1 );
add_action( 'woocommerce_checkout_create_order', 'save_event_venue_data_as_metadata', 10, 1 );
function save_event_venue_data_as_metadata( $object ) {
if ( is_a($object, 'WC_Order') ) {
save_customer_event_venue_data( $object );
} else {
save_customer_event_venue_data( $object, 'customer' );
}
}
// Display Event data on orders, admin orders and email notifications
add_action('woocommerce_after_order_details', 'display_event_data_on_orders', 10, 1);
add_action('woocommerce_admin_order_data_after_shipping_address', 'display_event_data_on_orders', 10, 1 );
function display_event_data_on_orders( $order ) {
$event_data = get_customer_event_venue_data( $order );
$event_title = __('Event details', 'woocommerce');
if ( ! empty($event_data) ) {
// On admin orders
if( is_admin() ) {
echo '<h3>'.$event_title.'</h3><p>';
foreach ( $event_data as $label => $value ) {
echo '<strong>' . $label .':</strong> ' . $value . '<br>';
}
echo '</p>';
}
// On customer orders and thankyou
else {
echo '<h2 class="woocommerce-column__title">'.$event_title.'</h2>
<table class="woocommerce-table woocommerce-table--event-details shop_table event_details"><tfoot>';
foreach ( $event_data as $label => $value ) {
echo '<tr class="event-venue"><th>'.$label.'</th><td>'.$value.'</td></tr>';
}
echo '</tfoot></table>';
}
}
}
// Display Event data on email notifications
add_action('woocommerce_email_after_order_table', 'display_event_data_on_email_notifications', 10, 1);
function display_event_data_on_email_notifications( $order ) {
$event_data = get_customer_event_venue_data( $order );
$event_title = __('Event details', 'woocommerce');
if ( ! empty($event_data) ) {
echo '<style>
.event-info table{width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
color: #737373; border: 1px solid #e4e4e4; margin-bottom:8px;}
.event-info table th, table.tracking-info td{text-align: left; border-top-width: 4px;
color: #737373; border: 1px solid #e4e4e4; padding: 12px; width:58%;}
.event-info table td{text-align: left; border-top-width: 4px; color: #737373; border: 1px solid #e4e4e4; padding: 12px;}
</style>';
echo '<div class="event-info"><h2>'.$event_title.'</h2>';
echo '<table cellspacing="0" cellpadding="6"><tbody>';
foreach ( $event_data as $label => $value ) {
echo '<tr"><th>'.$label.'</th><td>'.$value.'</td></tr>';
}
echo '</tbody></table></div><br>';
}
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.
You will get (screenshots):
Related: Add custom meta data into emails as a html styled table with a title in Woocommerce