Search code examples
phpwordpresswoocommerceproduct

Display the selected WooCommerce variation formatted price with shortcode


I have created this piece of code that displays the price on any page on the website, which is controlled by woocommerce.

add_shortcode( 'hhs_product_price', 'hhs_woo_product_price_shortcode' );

function hhs_woo_product_price_shortcode( $atts ) {

    $atts = shortcode_atts( array(

        'id' => null

    ), $atts, 'hhs_product_price' );
 

    if ( empty( $atts[ 'id' ] ) ) {

        return '';

    }

    $product = wc_get_product( $atts['id'] );

    if ( ! $product ) {

        return '';

    }

    return $product->get_price_html();
} 

What I would like to do is modify the code so that if a customer selects a product with a variation. Then the price changes to display the variation price. For example right now if a person selects a product, in this case a tincture bottle, with a price variation connected to the size of the bottle. On the products page they see the following:-

Product (Tincture) $30 - $50

From a drop down menu they can select an option of either 10mg bottle ($30), 15mg bottle ($40), or 20mg bottle ($50). So if a person selects option 20mg the price should display $50 instead of $30 - $50

I have already looked at various posts on stackoverflow with a similar problem but non of those solutions are working for me

Any help would be greatly appropriated.

Thank you


Solution

  • To display the selected product price from a variation on variable products, jQuery is required. So the following shortcode will handle all product types, including variable products and their price variations:

    add_shortcode( 'product_price', 'display_formatted_product_price' );
    function display_formatted_product_price( $atts ) {
        extract(shortcode_atts( array(
            'id' => null
        ), $atts, 'product_price' ) );
    
        global $product;
    
        if( ! empty($id) || ! is_a($product, 'WC_Product') ) {
            $product = wc_get_product( empty($id) ? get_the_id() : $id );
        }
    
        $price_html = $product->get_price_html();
    
        // Others product types than variable
        if ( ! $product->is_type('variable') ) {
            return '<span class="product-price">' . $price_html . '</span>';
        }
        // For variable products
        else {
            ob_start();
    
            ?>
            <script type="text/javascript">
            jQuery( function($){
                var p = '<?php echo $price_html; ?>', s = 'span.product-price';
    
                $( 'form.variations_form.cart' ).on('show_variation', function(event, data) {
                    $(s).html(data.price_html); // Display the selected variation price
                });
    
                $( 'form.variations_form.cart' ).on('hide_variation', function() {
                    $(s).html(p); // Display the variable product price range
                });
            });
            </script>
            <?php
    
            return ob_get_clean() . '<span class="product-price">' . $price_html . '</span>';
        }
    }
    

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


    USAGE:

    Use [product_price] or in php code echo do_shortcode('[product_price]').

    You can also define a product id like (for example for product id 37): [product_price id="37"]