Recently my client requested additional custom checkout fields for their WooCommerce-based website selling tickets as digital products, in order to get the information about their attendees, they need to gather the details below:
- Fullname
- Email Address
- Mobile No.
- Job Title
- Company
The first step is to add custom input checkout fields to the Checkout page based on the number of cart items, and we’re targetting to show these fields after the Order Notes field. We will be hooking our script with the ‘woocommerce_after_order_notes’ hook
1. Displaying Input fields based on cart item count
// Add input field group for attendees based on cart item count
add_action('woocommerce_after_order_notes', 'hr_attendee_input_fields', 20);
function hr_attendee_input_fields(){
$checkout = WC()->checkout;
$cart_item_count = WC()->cart->get_cart_contents_count() + 1;
echo '<div id="container">';
for ($i=1; $i < $cart_item_count; $i++) {
echo '<div class="attendee" id="attendee-'.$i.'">';
echo '<h3 class="attendee-heading">';
esc_html_e('Attendee '.$i, 'woocommerce');
echo '</h3>';
echo '<div class="row">';
woocommerce_form_field('_attendee-firstname-' . $i, array(
'type' => 'text',
'label' => __('First name', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide form-row-first'),
'required' => true, // or false
), $checkout->get_value('_attendee-firstname-' . $i));
woocommerce_form_field('_attendee-lastname-' . $i, array(
'type' => 'text',
'label' => __('Last name', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide form-row-last'),
'required' => true, // or false
), $checkout->get_value('_attendee-lastname-' . $i));
echo '</div>';
woocommerce_form_field('_attendee-company-' . $i, array(
'type' => 'text',
'label' => __('Company', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide'),
'required' => true, // or false
), $checkout->get_value('_attendee-company-' . $i));
woocommerce_form_field('_attendee-jobtitle-' . $i, array(
'type' => 'text',
'label' => __('Job title', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide'),
'required' => false, // or false
), $checkout->get_value('_attendee-jobtitle-' . $i));
woocommerce_form_field('_attendee-email-' . $i, array(
'type' => 'text',
'label' => __('Email', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide'),
'required' => true, // or false
), $checkout->get_value('_attendee-email-' . $i));
woocommerce_form_field('_attendee-mobile-' . $i, array(
'type' => 'text',
'label' => __('Mobile', $domain),
'placeholder' => __('', $domain),
'class' => array('form-row-wide'),
'required' => true, // or false
), $checkout->get_value('_attendee-mobile-' . $i));
echo '</div>';
}
echo '</div>';
}
2. Save the attendee information to the database
add_action('woocommerce_checkout_update_order_meta', 'hr_save_attendee_details');
function hr_save_attendee_details($order_id)
{
$cart_item_count = WC()->cart->get_cart_contents_count() + 1;
for ($i=1; $i < $cart_item_count; $i++) {
if (!empty($_POST['_attendee-firstname-' . $i])) {
update_post_meta($order_id, '_attendee-firstname-' . $i, sanitize_text_field($_POST['_attendee-firstname-' . $i]));
}
if (!empty($_POST['_attendee-lastname-' . $i])) {
update_post_meta($order_id, '_attendee-lastname-' . $i, sanitize_text_field($_POST['_attendee-lastname-' . $i]));
}
if (!empty($_POST['_attendee-company-' . $i])) {
update_post_meta($order_id, '_attendee-company-' . $i, sanitize_text_field($_POST['_attendee-company-' . $i]));
}
if (!empty($_POST['_attendee-jobtitle-' . $i])) {
update_post_meta($order_id, '_attendee-jobtitle-' . $i, sanitize_text_field($_POST['_attendee-jobtitle-' . $i]));
}
if (!empty($_POST['_attendee-email-' . $i])) {
update_post_meta($order_id, '_attendee-email-' . $i, sanitize_text_field($_POST['_attendee-email-' . $i]));
}
if (!empty($_POST['_attendee-mobile-' . $i])) {
update_post_meta($order_id, '_attendee-mobile-' . $i, sanitize_text_field($_POST['_attendee-mobile-' . $i]));
}
}
}
3. Display the attendee information to the Success Order Page, Admin Edit Screen page and Email
// Display attendee details
add_action('woocommerce_order_details_after_order_table', 'hr_display_attendee_details');
// Order received and view
add_action('woocommerce_email_after_order_table', 'hr_display_attendee_details');
// Email notifications
add_action('woocommerce_admin_order_data_after_billing_address', 'hr_display_attendee_details');
function hr_display_attendee_details($order)
{
echo '<h2>' . __('Attendee Details:', 'woocommerce') . '</h2>';
echo '<div><table class="customer-details" cellspacing="0">';
// Loop through order items
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$item_count = $item->get_quantity();
// Loop through item quantity
for ($i = 1; $i <= $item_count; $i++) {
echo '<tr>';
echo '<td>';
echo '<strong style="font-size: 20px; display: block; border-bottom: 1px solid rgba(0,0,0,.1);">' . __("Attendee " . $i, "woocommerce") . ': </strong><br/>';
echo '<strong>' . __("Full Name ", "woocommerce") . ': </strong>';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-firstname-'.$i, true) . ' ';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-lastname-'.$i, true);
echo '<br/><br/>';
// Company
echo '<strong>' . __("Company ", "woocommerce") . ': </strong>';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-company-'.$i, true);
echo '<br/><br/>';
// Job Title
echo '<strong>' . __("Job Title ", "woocommerce") . ': </strong>';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-jobtitle-'.$i, true);
echo '<br/><br/>';
// Email
echo '<strong>' . __("Email ", "woocommerce") . ': </strong>';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-email-'.$i, true);
echo '<br/><br/>';
// Mobile
echo '<strong>' . __("Mobile ", "woocommerce") . ': </strong>';
echo get_post_meta($item->get_order_id(), '_ff-wc-attendee-mobile-'.$i, true);
echo '<br/><br/>';
echo '</td></tr>';
}
break;
}
echo '</table></div>';
}