phpjquerywoocommerceproduct-variationsavailability

Show a custom text on WooCommerce variable products when no variation is selected


I have a product with different variations. To choose an variation two select fields have to be filled. However, the availability message is only shown when both select fields have a option selected. I want to show a general availability message as long as not variation is selected: "Choose location and date to see availability".

I know how to change the message with the "woocommerce_get_availability_text"-filter. But I don't know how to present this message right from the page load and which part of WooCommerce's JavaScript I have to change in order to make it work.

I think the following is necessary:

  1. Adding <div class="woocommerce-variation-availability">Choose location and date to see availability</div> to content-single-product.php, so that the general message is shown right at the page load.

  2. Add some JS which puts the in-stock and out-of-stock messages to the div as soon as a variation is selected. The JS has also to take care that the general message gets display again as soon as no variation is selected anymore.


Solution

  • To show a custom text on variable products when no variation is selected use the following:

    add_action( 'woocommerce_before_variations_form', 'display_variation_availability_message_js' );
    function display_variation_availability_message_js() {
        global $product;
    
        $custom_text_html = sprintf('<div class="wc-availability" style="display:none">%s</div>',
            __('Choose location and date to see availability', 'woocommerce')
        );
    
        wc_enqueue_js("const a = '.wc-availability';
        $('.single_variation_wrap').prepend('{$custom_text_html}');
        $('form.cart').on('show_variation hide_variation', function(e) {
            e.type === 'show_variation' ? $(a).hide() : $(a).show();
        });");
    }
    

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


    To target specific variable products only, replace in the function:

        global $product;
    

    with:

        global $product;
    
        // Here below define the targeted variable product IDs in the array
        $specific_products_ids = array( 15, 37, 108 );
    
        if ( ! in_array( $product->get_id(), $specific_products_ids ) ) return;
    

    Edit:

    As the existing parent <div class="woocommerce-variation single_variation"> for <div class="woocommerce-variation-availability"> child element, get hidden (slideDown usage by WooCommerce), when there are no variations selected you can not use it to display your custom div inside <div class="woocommerce-variation-availability">.

    It's not really possible to change the behavior slideUp / slideDown that WooCommerce is doing on <div class="woocommerce-variation single_variation">, without editing the WooCommerce JS files.

    Here is a revisited code version using a <div> container and slideUp() / slideDown() methods instead of show() / hide() methods:

    add_action( 'woocommerce_before_variations_form', 'display_variation_availability_message_js' );
    function display_variation_availability_message_js() {
        global $product;
    
        $custom_text_html = sprintf('<div class="vcontainer" style="display:none">'.
            '<div class="wc-availability">%s</div></div>',
            __('Choose location and date to see availability', 'woocommerce')
        );
    
        wc_enqueue_js("$('.single_variation_wrap').prepend('{$custom_text_html}');
        $('form.cart').on('show_variation hide_variation', function(e) {
            e.type === 'show_variation' ? $('.vcontainer').slideUp(200) : $('.vcontainer').slideDown(200);
        });");
    }
    

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

    This doesn't sole the problem as you would like in your comment, but it uses the same behavior as WooCommerce.