GunStreetGirl
GunStreetGirl

Reputation: 303

Add conditionally a custom checkout field to shipping section in WooCommerce

I have certain Woocommerce products that require the customer (or the product recipient) to provide a date of birth. Customers are required to provide date of birth when creating an account to check out so I'm all set there, but I need to add a required DOB field to the shipping section if "Ship to a different address" is checked and if any item in the cart is one where date of birth is required.

Here's what I've tried:

add_filter( 'woocommerce_checkout_fields' , 'real_dob' );

function real_dob( $fields ) {

    $fields['shipping']['real_dob'] = array(

        'type' => 'text',
        'class'=> array( 'form_right_half', 'req'),
        'label' => __('Birthdate'),
        'required' => true,
     );

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
    $dob_check = get_post_meta( $cart_item['product_id'], 'require-dob', true );

    if ( $dob_check == 1 ) {
        $dob = true;
        break;
    }}

    if ($dob)
        return $fields; 
} 

This works when a product in the cart requires date of birth—the custom field is added. But if no product in the cart requires DOB, then none of the checkout fields load at all, neither billing nor shipping. What am I missing?

Upvotes: 2

Views: 423

Answers (2)

LoicTheAztec
LoicTheAztec

Reputation: 253783

In a filter hook, you need to always return, at the end, the first function argument, which is here $fields. Try the following functional simpler way:

add_filter( 'woocommerce_checkout_fields' , 'add_real_dob_checkout_field' );
function add_real_dob_checkout_field( $fields ) {
    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        // Check for 'require-dob' custom field
        if( get_post_meta( $cart_item['product_id'], 'require-dob', true ) == 1 ) { 
            $fields['shipping']['real_dob'] = array(
                'type' => 'text',
                'class'=> array( 'form_right_half', 'req'),
                'label' => __('Birthdate'),
                'required' => true,
            );
            break; // Stop the loop
        }
    }
    return fields; // Always return the main function argument at the end for a filter hook
} 

Upvotes: 1

MrEbabi
MrEbabi

Reputation: 740

Since the filter does not return anything when the cart contains no DOB products, it shows neither billing nor shipping field in the checkout.

You can revise your code like that:

add_filter( 'woocommerce_checkout_fields' , 'real_dob' );

function real_dob( $fields ) {

    //if(cart DOES NOT contain any DOB products)
    if(true)
    {
        return $fields;
    }
    //if(cart contains DOB products)
    else
    {
        $fields['shipping']['real_dob'] = array(
            'type' => 'text',
            'class'=> array( 'form_right_half', 'req'),
            'label' => __('Birthdate'),
            'required' => true,
         );
       return $fields; 
    }  
} 

Just tested and works fine. Have a good day.

Upvotes: 2

Related Questions