Woocommerce custom availability text shown multipl

2020-04-19 07:01发布

问题:

I'm experiencing the following bug on a clients WooCommerce website. We use this free Variations Swatch for Woocommerce plugin. I have a variable product with 4 different colors.

If all colors are sold out, when selecting a variation the "out of stock" custom message is shown.
But when selecting a different variation the message is shown again, so there are now 2 blocks with "out of stock" custom message:

I have a different product in this store with color and engine variations and there's no issue like this.

Question:
How can I make the out of stock custom message to be shown only once at the same time?

Here is the website live link to the product page, where the issue can be seen.

This is my code in the functions.php file of my theme:

// Change location of
add_action( 'woocommerce_single_product_summary', 'custom_wc_template_single_price', 10 );

function custom_wc_template_single_price(){
global $product;

// Variable product only
if($product->is_type('variable')):

    // Main Price
    $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
    $price = $prices[0] !== $prices[1] ? sprintf( __( 'Ab: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    // Sale Price
    $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
    sort( $prices );
    $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    if ( $price !== $saleprice && $product->is_on_sale() ) {
        $price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
    }

    ?>
    <style>
        div.woocommerce-variation-price,
        div.woocommerce-variation-availability,
        div.hidden-variable-price {
            height: 0px !important;
            overflow:hidden;
            position:relative;
            line-height: 0px !important;
            font-size: 0% !important;
        }
    </style>
    <script>
    jQuery(document).ready(function($) {
        $('select').blur( function(){
            if( '' != $('input.variation_id').val() ){
                if($('p.availability')) $('p.availability').remove();
                $('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
                console.log($('input.variation_id').val());
            } else {
                $('p.price').html($('div.hidden-variable-price').html());
                if($('p.availability'))
                    $('p.availability').remove();
                console.log('NULL');
            }
        });
    });
    </script>
    <?php

    echo '<p class="price">'.$price.'</p>
    <div class="hidden-variable-price" >'.$price.'</div>';

endif;
}


// This filter for custom in stock and out of stock messages:

add_filter( 'woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability( $availability, $_product ) {


    // Change In Stock Text
    if ( $_product->is_in_stock() ) {
        $availability['availability'] = __('Dein Minimoto Produkt ist verfügbar!', 'woocommerce');
    }
    // Change Out of Stock Text
    if ( ! $_product->is_in_stock() ) {
        $availability['availability'] = __('Aktuell nicht vorrätig, bitte kontaktieren Sie uns telefonisch unter +49 403 486 2392', 'woocommerce');
    }
    return $availability;
}

回答1:

Update: I have changed in your code:

'<p class="availability">+$('div.woocommerce-variation-availability').html()+</p>' 

To:

'<div class="availability">+$('div.woocommerce-variation-availability').html()+</div>'

Avoiding repetitive malformed html <p> and </p> tags…

And changed:

if($('p.availability')) $('p.availability').remove();

To this better one:

if($('div.availability').html() != undefined ) $('div.availability').remove();

I have simplified the code in your wcs_custom_get_availability() function too…

So the correct code should be:

add_filter( 'woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability( $availability, $product ) {

    // Change In Stock Text
    if ( $product->is_in_stock() )
        $availability['availability'] = __('Dein Minimoto Produkt ist verfügbar!', 'woocommerce');
    else
        $availability['availability'] = __('Aktuell nicht vorrätig, bitte kontaktieren Sie uns telefonisch unter +49 403 486 2392', 'woocommerce');

    return $availability;
}

// Change location of
add_action( 'woocommerce_single_product_summary', 'custom_wc_template_single_price', 10 );
function custom_wc_template_single_price(){
    global $product;

    // Variable product only
    if($product->is_type('variable')):

        // Main Price
        $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
        $price = $prices[0] !== $prices[1] ? sprintf( __( 'Ab: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

        // Sale Price
        $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
        sort( $prices );
        $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

        if ( $price !== $saleprice && $product->is_on_sale() ) {
            $price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
        }

        ?>
        <style>
            div.woocommerce-variation-price,
            div.woocommerce-variation-availability,
            div.hidden-variable-price {
                height: 0px !important;
                overflow:hidden;
                position:relative;
                line-height: 0px !important;
                font-size: 0% !important;
            }
        </style>
        <script>
        jQuery(document).ready(function($) {
            $('select').blur( function(){
                var availability = '<div class="availability">'+$('div.woocommerce-variation-availability').html()+'</div>';
                if( '' != $('input.variation_id').val() ){
                    if($('div.availability').html() != undefined ) $('div.availability').remove(); // Just in case
                    $('p.price').html($('div.woocommerce-variation-price > span.price').html()).append(availability);
                    console.log('IF - '+$('input.variation_id').val());
                } else {
                    $('p.price').html($('div.hidden-variable-price').html());
                    if($('div.availability').html() != undefined ) $('div.availability').remove();
                    console.log('ELSE');
                }
            });
        });
        </script>
        <?php

        echo '<p class="price">'.$price.'</p>
        <div class="hidden-variable-price" >'.$price.'</div>';

    endif;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and work … This should solve your issue.



回答2:

This row tells you everything

 $('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');

you are using append not html()

change your code to:

$('p.price').html($('div.woocommerce-variation-price > span.price').html()+'<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');