简体   繁体   中英

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?

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.

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
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM