I am trying to add a dropdown field at checkout which needs to be validated before order submission and stored in the order for admin to view in order details. But for some reason even after i select the dropdown option, it says a value must be selected for the field.
add_filter( 'woocommerce_after_checkout_form', 'custom_checkout_fields' ); function custom_checkout_fields( $checkout ) { // The selector woocommerce_form_field( 'allow_substitute', array( 'type' => 'select', 'required' => true, 'class' => array('my-field-class form-row-wide'), 'label' => __('Allow Product substitution when a cigar is out of stock?', 'my_theme_slug'), 'options' => array( '' => __('Choose an option', 'my_theme_slug'), 'option1' => 'Allow product substitution (When a cigar is out of stock, a similar cigar will be shipped.', 'option2' => 'Call me before making a product substitution', 'option3' => 'Refund the cigar order value that is out of stock' ) ), $checkout->get_value( 'allow_substitute' )); echo '</div>'; } // Process the checkout add_action('woocommerce_checkout_process', 'custom_checkout_field_process'); function custom_checkout_field_process() { // Check if set, if its not set add an error. if ( ! $_POST['allow_substitute'] ) // the selector wc_add_notice( __( 'Please select a value for "Product Substitution?" field.' ), 'error' ); } // Update the order meta with field value add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta' ); function custom_checkout_field_update_order_meta( $order_id ) { if ( ! empty( $_POST['allow_substitute'] ) ) { update_post_meta( $order_id, 'allow_substitute', sanitize_text_field( $_POST['allow_substitute'] ) ); } }
Advertisement
Answer
You can’t add a custom checkout field outside the checkout form, as it’s not posted… Use the following complete replacement code instead:
// Function with the array of options key / values pairs for the select field function get_allow_substitute_field_options() { $text_domain = 'my_theme_slug'; return array( '' => __('Choose an option', $text_domain), '1' => __('Allow product substitution (When a cigar is out of stock, a similar cigar will be shipped.', $text_domain), '2' => __('Call me before making a product substitution', $text_domain), '3' => __('Refund the cigar order value that is out of stock', $text_domain) ); } // Display the select field add_filter( 'woocommerce_checkout_after_order_review', 'custom_checkout_select_field', 50 ); function custom_checkout_select_field() { $text_domain = 'my_theme_slug'; // The select field woocommerce_form_field( 'allow_substitute', array( 'type' => 'select', 'required' => true, 'class' => array('my-field-class form-row-wide'), 'label' => __('Allow Product substitution when a cigar is out of stock?', $text_domain), 'options' => get_allow_substitute_field_options(), ), WC()->checkout->get_value( 'allow_substitute' )); echo '</div>'; } // Checkout select field validation add_action('woocommerce_after_checkout_validation', 'custom_checkout_select_field_validation', 10, 2 ); function custom_checkout_select_field_validation( $data, $errors ) { // Check if set, if its not set add an error. if ( isset($_POST['allow_substitute']) && empty($_POST['allow_substitute']) ) { $errors->add( 'validation', __( 'Please select a value for "Product Substitution?" field.' ) ); } } // Save selected option as order meta data add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_order_meta' ); function custom_checkout_field_update_order_meta( $order ) { if ( isset($_POST['allow_substitute']) && ! empty($_POST['allow_substitute']) ) { $order->update_meta_data( 'allow_substitute', sanitize_text_field( $_POST['allow_substitute'] ) ); } } // Display "allow_substitute" option value on the order edit pages under billing section add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_allow_substitute_field_value_in_admin_orders', 10, 1 ); function display_allow_substitute_field_value_in_admin_orders($order){ $field_key = $order->get_meta('allow_substitute'); if ( ! empty($field_key) ) { $field_options = get_allow_substitute_field_options(); $field_value = $field_options[$field_key]; echo '<p> <strong>'.__('Product substitution').':</strong> <br> <small>' . $field_value . '</small> </p>'; } }
Code goes in functions.php file of the active child theme (or active theme). Tested and works.