Dynamic Custom Field on Checkout Based on Product Quantity featured

WooCommerce: Add Custom Field on Checkout Based on Product Quantity in Cart

In this tutorial, I will show you how to add dynamic checkout fields based on cart quantity on WooCommerce checkout page. The custom field will be multiply by product quantity, that means if a customer has 3 quantity in the cart then your custom field will repeat 3 times and display 3 fields on the checkout page.

Let’s say you have a booking system on your WooCommerce store and you want to capture the additional information at checkout if someone books for more than one quantity. For e.g., if you have Events/Workshops site and want to capture Name, Email, phone, and Address of everyone who attended your Event/Workshop and someone books for 3 quantity on your website then you need additional dynamic custom fields to capture the details of other 2 attendees. So if someone adds 3 quantity to the cart then the checkout page adds additional fields for other 2 attendees if 4 quantity added to the cart then it adds fields for other 3 attendees.

Within the following function, we will check how many quantities the user has in their cart and adds the additional fields to the checkout page if the quantity is more than 1. And save the field values to display it in the order in admin side.

Go to your functions.php file and add the following code at the end of the file or you can create your own plugin to add this function.

//Custom WooCommerce Checkout Fields based on Quantity
add_action( 'woocommerce_before_order_notes', 'person_details' );

function person_details($checkout) {
    global $woocommerce;
$count = $woocommerce->cart->cart_contents_count;
$i = 1;
       for($k=2; $k<= $count; $k++) {
		$i++;
		   print ('<h3>Please enter details of attendee '.$i.'</h3>');
		woocommerce_form_field( 'cstm_full_name'.$i, array(
        	'type'          => 'text',
        	'class'         => array('my-field-class form-row-wide'),
        	'label'         => __('Full name'),
        	'placeholder'   => __('Enter full name'),
        	),
        	$checkout->get_value( 'cstm_full_name'.$i ));
		echo '<div class="clear"></div>';
		woocommerce_form_field( 'cstm_phone'.$i, array(
        	'type'          => 'text',
        	'class'         => array('my-field-class form-row-first'),
        	'label'         => __('Phone'),
        	'placeholder'   => __('Enter phone number'),
        	),
        	$checkout->get_value( 'cstm_phone'.$i ));
		woocommerce_form_field( 'cstm_email'.$i, array(
        	'type'          => 'email',
        	'class'         => array('my-field-class form-row-last'),
        	'label'         => __('Email address'),
        	'placeholder'   => __('Enter email address'),
        	),
        	$checkout->get_value( 'cstm_email'.$i ));
		echo '<div class="clear"></div>';
		woocommerce_form_field( 'cstm_address'.$i, array(
        	'type'          => 'textarea',
        	'class'         => array('my-field-class form-row-wide'),
        	'label'         => __('Full address'),
        	'placeholder'   => __('Enter full address'),
        	),
        	$checkout->get_value( 'cstm_address'.$i ));
}
}

/**
 * Save value of fields
 */
 
add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta');
 
function customise_checkout_field_update_order_meta($order_id) {
	global $woocommerce;
$count = $woocommerce->cart->cart_contents_count;
$i = 1;
       for($k=2; $k<= $count; $k++) {
		$i++;
	if (!empty($_POST['cstm_full_name'.$i])) {
		update_post_meta($order_id, 'Name of Attendee'.$i, sanitize_text_field($_POST['cstm_full_name'.$i]));
	}
	if (!empty($_POST['cstm_phone'.$i])) {
		update_post_meta($order_id, 'Phone of Attendee'.$i, sanitize_text_field($_POST['cstm_phone'.$i]));
	}
	if (!empty($_POST['cstm_email'.$i])) {
		update_post_meta($order_id, 'Email of Attendee'.$i, sanitize_text_field($_POST['cstm_email'.$i]));
	}
	if (!empty($_POST['cstm_address'.$i])) {
		update_post_meta($order_id, 'Address of Attendee'.$i, sanitize_text_field($_POST['cstm_address'.$i]));
	}
}
}

/**
 * Add fields to order emails
 **/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_checkout_field_order_meta_keys( $keys ) {
$i = 1;
for($k=2; $k<= 50; $k++) {
$i++;
$keys[] = 'Name of Attendee'.$i;
$keys[] = 'Phone of Attendee'.$i;
$keys[] = 'Email of Attendee'.$i;
$keys[] = 'Email of Participant '.$i;
$keys[] = 'Address of Attendee'.$i;
}	
return $keys;
}

Dynamic custom fields on checkout page

Dynamic Custom Field on Checkout Based on Product Quantity 1

Custom Fields value on order page in admin

The following two tabs change content below.

Wasim Sama

Wasim Sama is a passionate blogger and experienced web developer.

14 thoughts on “WooCommerce: Add Custom Field on Checkout Based on Product Quantity in Cart

  1. Hi Wasim, how are you?

    I used you code from post WooCommerce: Add Dynamic Custom Field on Checkout Based on Product Quantity in Cart and it works perfectly. However, how do i change the field from optional to required?

    Thank you in advance!

    • Dear Wan,

      Just add ‘required’ => true, to make a field required.

      For Example:

      woocommerce_form_field( 'cstm_full_name'.$i, array(
              	'type'          => 'text',
              	'class'         => array('my-field-class form-row-wide'),
              	'label'         => __('Full name'),
              	'placeholder'   => __('Enter full name'),
              	'required' => true,
              	),
              	$checkout->get_value( 'cstm_last_name'.$i ));
      
    • Hey Max,

      This plugin can’t be altered for Woocommerce Booking extension as it has many other features. This snippet is only getting other peoples details if there are multiple quantities in the cart.

  2. Hey Wasim,
    Thanks so much for your post, that’s exactly what I am trying to do.
    I copied your code in functions.php but it didn’t work for me.
    I am just starting with Woocommerce, so I appreciate any help you can give me on how I can make this work.
    Do I need to add anything else for this to work?
    Regards,
    Leon

  3. Hi Wasim

    We’ve added the code above to our functions.php. Now we want to display the fields in the confirmation e-mail. How can we do this?

    Thanks for your feedback and greetings
    Larissa

    • Hello Larissa,

      Please use the following snippet to add fields in the order notification email.

      /**
       * Add the field to order emails
       **/
      add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
      function my_custom_checkout_field_order_meta_keys( $keys ) {
      $i = 1;
      for($k=2; $k<= 50; $k++) {
      $i++;
      $keys[] = 'Name of Attendee'.$i;
      $keys[] = 'Phone of Attendee'.$i;
      $keys[] = 'Email of Attendee'.$i;
      $keys[] = 'Email of Participant '.$i;
      $keys[] = 'Address of Attendee'.$i;
      }	
      return $keys;
      }
      

      I also have added this snippet in the post. Please check complete code in the post above.

      • Hi Wasim

        Thank’s for your feedback.
        I’ve added the snippet like this:
        _____________________________________

        get_formatted_billing_full_name() ); ?>
        <?php

        /*
        * @hooked WC_Emails::order_details() Shows the order details table.
        * @hooked WC_Structured_Data::generate_order_data() Generates structured data.
        * @hooked WC_Structured_Data::output_structured_data() Outputs structured data.
        * @since 2.5.0
        */
        do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::order_meta() Shows order meta data.
        */
        do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::customer_details() Shows customer details
        * @hooked WC_Emails::email_address() Shows email address
        */
        do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::email_footer() Output the email footer
        */
        do_action( 'woocommerce_email_footer', $email );

        add_filter(‘woocommerce_email_order_meta_keys’, ‘my_custom_checkout_field_order_meta_keys’);
        function my_custom_checkout_field_order_meta_keys( $keys ) {
        $i = 1;
        for($k=2; $k<= 50; $k++) { $i++; $keys[] = 'Name of Attendee'.$i; $keys[] = 'Phone of Attendee'.$i; $keys[] = 'Email of Attendee'.$i; $keys[] = 'Email of Participant '.$i; $keys[] = 'Address of Attendee'.$i; } return $keys; }
        _____________________________________

        But unfortunately doesn't work.

        Thank's for your help and greetings
        Larissa

        • Hello Larissa,

          It Looks Like you added the snippet in Woocommerce email template. You need to add this snippet in function file where you added other code to display fields on the checkout. Also, replace ‘Name of Attendee’, ‘Phone of Attendee’, ‘Email of Attendee’, ‘Email of Participant ‘, ‘Address of Attendee’ with your field names.

  4. Hi there. This works so very well except that although highlighting the fields in the additional inforamtion section after adding the required = true, it will still let the user skip through to checkout. Any reason why that you can think of?

    • You need to add validation for the required field.

      For Example:

      function person_details($checkout) {
          global $woocommerce;
      $count = $woocommerce->cart->cart_contents_count;
      $i = 1;
             for($k=2; $k<= $count; $k++) {
      		$i++;
      		print ('Please enter details of attendee '.$i);
      		woocommerce_form_field( 'cstm_full_name'.$i, array(
              	'type'          => 'text',
              	'class'         => array('my-field-class form-row-wide'),
              	'label'         => __('Full name'),
              	'placeholder'   => __('Enter full name'),
              	'required' => true,
              	),
              	$checkout->get_value( 'cstm_full_name'.$i ));
             }
      }
      
      /**
       * For data validation of the custom field.
       */
      add_action('woocommerce_checkout_process', 'customise_checkout_field_process');
      function customise_checkout_field_process() {
      global $woocommerce;
      $count = $woocommerce->cart->cart_contents_count;
      $i = 1;
             for($k=2; $k<= $count; $k++) {
      	  $i++;
      	  // if the field is set, if not then show an error message.
      	  if (!$_POST['cstm_full_name'.$i]) wc_add_notice(__('Full name of ATTENDEE '.$i.' is a required field.') , 'error');
             }	
      }
      

Leave a Reply

Your email address will not be published. Required fields are marked *