skip to Main Content

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.

2

Answers


  1. Your code tries to determine the current product ID based on the items in the cart. This approach assumes that only one product can be in the cart at a time. If you have multiple products in the cart, it will only use the product ID of the first item. To handle multiple products, you should collect all the product IDs in an array and then apply your conditional logic.

    Here’s a modified version of your 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_ids = array();
    
        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_ids[] = $product->get_id();
                }
            }
        }
    
        // Remove fields by default
        unset( $fields['billing_participating_location'] );
        unset( $fields['billing_toxicology'] );
        unset( $fields['billing_artificial_intelligence'] );
    
        // Check if fields should be added based on current product IDs
        if ( array_intersect( $current_product_ids, $product_ids_participating_location ) ) {
            $fields['billing_participating_location'] = array(
                'label'    => 'Participating Location',
                'required' => true,
                'class'    => array( 'form-row-wide' ),
                'clear'    => true,
            );
        }
    
        if ( array_intersect( $current_product_ids, $product_ids_toxicology ) ) {
            $fields['billing_toxicology'] = array(
                'label'    => 'Toxicology',
                'required' => true,
                'class'    => array( 'form-row-wide' ),
                'clear'    => true,
            );
        }
    
        if ( array_intersect( $current_product_ids, $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' );
    

    With this, it collect all current product IDs in the $current_product_ids array and then uses array_intersect to determine if each field should be added based on the product IDs.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search