Search code examples
phpwordpresswoocommercehook-woocommercewoocommerce-theming

How to display custom WooCommerce billing fields based on product IDs


I want to show/hide custom fields on the checkout page based on Product IDs. Therefore, I am using the following code:

function display_custom_checkout_fields_based_on_product( $fields ) {
    $product_ids_participating_location = array( 5503 );
    $product_ids_toxicology = array( 5453, 5454, 5455 );
    $product_ids_artificial_intelligence = array( 5453, 5454, 5455, 5496 );

    $current_product_id = 0;

    if ( WC()->cart && WC()->cart->get_cart() ) {
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = $cart_item['data'];
            if ( $product && is_a( $product, 'WC_Product' ) ) {
                $current_product_id = $product->get_id();
                break;
            }
        }
    }

    unset( $fields['billing_participating_location'] );
    unset( $fields['billing_toxicology'] );
    unset( $fields['billing_artificial_intelligence'] );

    if ( in_array( $current_product_id, $product_ids_participating_location ) ) {
        $fields['billing_participating_location'] = array(
            'label'    => 'Participating Location',
            'required' => true,
            'class'    => array( 'form-row-wide' ),
            'clear'    => true,
        );
    }

    if ( in_array( $current_product_id, $product_ids_toxicology ) ) {
        $fields['billing_toxicology'] = array(
            'label'    => 'Toxicology',
            'required' => true,
            'class'    => array( 'form-row-wide' ),
            'clear'    => true,
        );
    }

    if ( in_array( $current_product_id, $product_ids_artificial_intelligence ) ) {
        $fields['billing_artificial_intelligence'] = array(
            'label'    => 'Artificial Intelligence',
            'required' => true,
            'class'    => array( 'form-row-wide' ),
            'clear'    => true,
        );
    }

    return $fields;
}

add_filter( 'woocommerce_checkout_fields', 'display_custom_checkout_fields_based_on_product' );

But it's not working as expected.

I want to show each field only for the related product IDs in the defined array.

Any help will be greatly appreciated.


Solution

  • There are some mistakes, unnecessary and missing things in your code:

    Use the following revisited code instead:

    add_filter( 'woocommerce_checkout_fields', 'display_custom_checkout_fields_based_on_cart_items' );
    function display_custom_checkout_fields_based_on_cart_items( $fields ) {
        $participating_location_ids  = array( 5503 );
        $toxicology_ids              = array( 5453, 5454, 5455 );
        $artificial_intelligence_ids = array( 5453, 5454, 5455, 5496 );
    
        $item_ids = array(); // Initializing
    
        // Collect cart items product IDs
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $item_ids[] = $cart_item['product_id'];
    
            if ( $cart_item['variation_id'] > 0 ) {
                $item_ids[] = $cart_item['variation_id'];
            }
        }
    
        // Check Ids to display 'billing_participating_location' field
        if ( count( array_intersect( $item_ids, $participating_location_ids ) ) > 0 ) {
            $fields['billing']['billing_participating_location'] = array(
                'label'    => 'Participating Location',
                'required' => true,
                'class'    => array( 'form-row-wide' ),
                'clear'    => true,
            );
        }
        // Check Ids to display 'billing_toxicology' field
        if ( count( array_intersect( $item_ids, $toxicology_ids ) ) > 0 ) {
            $fields['billing']['billing_toxicology'] = array(
                'label'    => 'Toxicology',
                'required' => true,
                'class'    => array( 'form-row-wide' ),
                'clear'    => true,
            );
        }
        // Check Ids to display 'billing_artificial_intelligence' field
        if ( count( array_intersect( $item_ids, $artificial_intelligence_ids ) ) > 0 ) {
            $fields['billing']['billing_artificial_intelligence'] = array(
                'label'    => 'Artificial Intelligence',
                'required' => true,
                'class'    => array( 'form-row-wide' ),
                'clear'    => true,
            );
        }
    
        return $fields;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.