Search code examples
phpwordpresswoocommerceproductcheckout

Woocommerce diplaying custom checkout field for specific product


I have created a custom checkout field which displays saves to the order page and sends in the admin email, everything seems to be working fine:

// Display a custom checkout select field after billing information
add_action( 'woocommerce_after_checkout_billing_form', 'my_custom_checkout_field', 10, 1 );
function my_custom_checkout_field( $checkout ) {
    echo '<div id="my_custom_checkout_field">
    <h2>' . __('Please select your Delivery Partner') . '</h2>';

    woocommerce_form_field( 'delivery_partner', array(
        'type'          => 'select',
        'options'     => array(
   't1' => __('t1', 'woocommerce' ),
   't2' => __('t2', 'woocommerce' ),
   't3' => __('t3', 'woocommerce' ),
   't4' => __('t4', 'woocommerce'),
   't5' => __('t5', 'woocommerce' )),
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Delivery Partner'),
        ), $checkout->get_value( 'delivery_partner' ));

    echo '</div>';
}

// Save the dropdown custom field selected value as order custom meta data:
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta', 10, 2 );
function my_custom_checkout_field_update_order_meta( $order, $data ) {
    if ( isset($_POST['delivery_partner']) && ! empty($_POST['delivery_partner']) ) {
        $order->update_meta_data( 'Delivery Partner', sanitize_text_field( $_POST['delivery_partner'] ) );
    } 
}

// Display the custom field value on admin order pages after billing adress:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ) {
    echo '<p><strong>'.__('Delivery Partner').':</strong> ' . $order->get_meta('Delivery Partner') . '</p>'; 
}

// Display the custom field value on "New Order" notification:
add_action( 'woocommerce_email_after_order_table', 'custom_woocommerce_email_order_meta_fields', 10, 4 );
function custom_woocommerce_email_order_meta_fields( $order, $sent_to_admin, $plain_text, $email ) {
    if( 'new_order' === $email->id )
        echo '<p><strong>'.__('delivery_partner').':</strong> ' . $order->get_meta('Delivery Partner') . '</p>';
}

What I am wanting is for all of this to work only for one product, ID6245, and not to display at all for all others.

Can someone please point me in the right direction?


Solution

  • To display your custom checkout fields only for a specific product, replace your first function with the following (defining the right product ID below):

    // Display a custom checkout select field after billing information
    add_action( 'woocommerce_after_checkout_billing_form', 'my_custom_checkout_field', 10, 1 );
    function my_custom_checkout_field( $checkout ) {
        // Define below the targeted product ID
        $targeted_product_id = 16;
    
        foreach( WC()->cart->get_cart() as $item ){
            if ( ! in_array($targeted_product_id, [$item['product_id'], $item['variation_id']]) ) {
                return; // Exit if there are other products in cart that the targeted one.
            }
        }
    
        echo '<div id="my_custom_checkout_field">
        <h2>' . __('Please select your Delivery Partner') . '</h2>';
    
        woocommerce_form_field( 'delivery_partner', array(
            'type'          => 'select',
            'options'     => array(
       't1' => __('t1', 'woocommerce' ),
       't2' => __('t2', 'woocommerce' ),
       't3' => __('t3', 'woocommerce' ),
       't4' => __('t4', 'woocommerce'),
       't5' => __('t5', 'woocommerce' )),
            'class'         => array('my-field-class form-row-wide'),
            'label'         => __('Delivery Partner'),
            ), $checkout->get_value( 'delivery_partner' ));
    
        echo '</div>';
    }
    

    Code goes on functions.php file of your child theme (or in a plugin). It should work.