Sophie
Sophie

Reputation: 85

WooCommerce display total price when quantity selection change

I'm in need of displaying the total price in product page when quantity changes.
This is the same as line price in the cart if you add quantity of products in the cart.
I'm still new with WooCommerce so I'm not sure where to start. But if someone could help me to the right direction, I think I can manage on my own.

So here's my thoughts on how should I do it.

I'm thinking my jquery would be like this.

jQuery(document).ready(function($){
    $('.qty').on('change',function(){
         // grab the price
         var price = $('[itemprop="price"]').attr('content');
         var total_price = price * this.value;
         console.log(price, this.value, total_price);
    });
})

this works when pasted on the console. But I'm not sure where to put this code on WooCommerce.

https://i.sstatic.net/uTfEy.png

Upvotes: 8

Views: 29127

Answers (5)

Ilya Novojilov
Ilya Novojilov

Reputation: 889

I think it's better to rely on events and data provided on value lower then element innerText.

My solution is follows (it also works if product is shown in the pop up , i.e. loaded dynamically )

add_filter( 'formatted_woocommerce_price', function($formatted, $row, $decimals, $decimal_separator, $thousand_separator ) {
  return is_product() ? '<span class=number>' . $formatted . '</span>' : $formatted;
},10, 5);

add_action('woocommerce_after_add_to_cart_quantity', function() {
global $product;
if (!$product->is_single()) return;
?>
    <input type="hidden" name="simple-product-price" value="<?php echo $product->get_price() ?>">

<?php
});

and somewhere in the javascript:

$('body').on('change', '[name=quantity]', function(e) {
    const form = this.closest('form')
    const priceinput = form.querySelector('[name=simple-product-price]')
    let unitprice = 0
    if (priceinput) {
      unitprice = priceinput.value
    } else {
      const data = JSON.parse(form.dataset['product_variations'])
      const currentvariation = form.querySelector('[name=variation_id]')
      if (!currentvariation) return
      const variation = data.find(variation => variation.variation_id == currentvariation.value)
      if (!variation) return
      unitprice = variation.display_price
    }
    const total = (unitprice * e.target.value).toFixed(2)
    form.querySelector('.single_variation_wrap .woocommerce-Price-amount .number').innerText = total
  })

Upvotes: 0

Stephen Whitmore
Stephen Whitmore

Reputation: 953

The answers here only helped me partially because I have both simple and variable products so I took @Reigel and @aphoe's answers and combined them:

<?php 

add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 );

function woocommerce_total_product_price() {
    global $woocommerce, $product;
    $product_type = $product->get_type(); ?> 

    <script>
        function addCommas(nStr) {
            nStr += '';
            const x = nStr.split('.');
            let x1 = x[0];
            const x2 = x.length > 1 ? '.' + x[1] : '';
            const rgx = /(\d+)(\d{3})/;
            while (rgx.test(x1)) {
                x1 = x1.replace(rgx, '$1' + ',' + '$2');
            }
            return x1 + x2;
        }

        function resetVariations() {
            jQuery('.reset_variations').click(function() {
                jQuery('.current-price').html('');
            });
        }

        function updateCurrentPrice(productType) {
            jQuery(function($){                
                let price = <?php echo $product->get_price(); ?>;
                const currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

                $('[name=quantity]').change(function(){
                    if (!(this.value < 1)) {
                        if (productType === 'variable') {
                            price = jQuery('.single_variation_wrap .woocommerce-Price-amount.amount bdi').first().contents().filter(function() {
                                return this.nodeType == 3;
                            }).text().replace(',','');
                        }

                        const product_total = parseFloat(price * this.value);

                        $('.current-price').html( currency + addCommas(product_total.toFixed(2)));
                    }
                });
            });
        }

        updateCurrentPrice('<?php echo $product_type; ?>');
        resetVariations();
    
    </script>
    <?php
}

Upvotes: 0

aphoe
aphoe

Reputation: 2716

This worked for me on a page with product variety

//allow this particular AJAX function for logged in users
add_action('wp_ajax_myajax', 'woocommerce_total_product_price');

//allow this particular AJAX function for non-logged in users
add_action('wp_ajax_nopriv_myajax', 'woocommerce_total_product_price');

add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 );
function woocommerce_total_product_price() {
    global $woocommerce, $product;
    // let's setup our divs
    echo sprintf('<div id="product_total_price" style="margin:20px auto;">%s %s</div>',__('Product Total:','woocommerce'),'<span class="price"></span>');
    ?>
        <script>
            jQuery(function($){
                //var price = <?php echo $product->get_price(); ?>,
                
                currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

                $('[name=quantity]').change(function(){
                    if (!(this.value < 1)) {
                        var price = jQuery('.single_variation_wrap .woocommerce-Price-amount.amount bdi').first().contents().filter(function() {
                            return this.nodeType == 3;
                        }).text().replace(',','');

                        var product_total = parseFloat(price * this.value);

                        $('#product_total_price .price').html( currency + addCommas(product_total.toFixed(2)));

                    }
                });
            });
            
            function addCommas(nStr) {
                nStr += '';
                var x = nStr.split('.');
                var x1 = x[0];
                var x2 = x.length > 1 ? '.' + x[1] : '';
                var rgx = /(\d+)(\d{3})/;
                while (rgx.test(x1)) {
                    x1 = x1.replace(rgx, '$1' + ',' + '$2');
                }
                return x1 + x2;
            }
        </script>
    <?php
}

Upvotes: 1

Reigel Gallarde
Reigel Gallarde

Reputation: 65254

You're almost there... try this, paste this in your functions.php

add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 );
function woocommerce_total_product_price() {
    global $woocommerce, $product;
    // let's setup our divs
    echo sprintf('<div id="product_total_price" style="margin-bottom:20px;">%s %s</div>',__('Product Total:','woocommerce'),'<span class="price">'.$product->get_price().'</span>');
    ?>
        <script>
            jQuery(function($){
                var price = <?php echo $product->get_price(); ?>,
                    currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

                $('[name=quantity]').change(function(){
                    if (!(this.value < 1)) {

                        var product_total = parseFloat(price * this.value);

                        $('#product_total_price .price').html( currency + product_total.toFixed(2));

                    }
                });
            });
        </script>
    <?php
}

source: http://reigelgallarde.me/programming/show-product-price-times-selected-quantity-on-woocommecre-product-page/ enter image description here

Upvotes: 19

Lucky_hunter
Lucky_hunter

Reputation: 496

You need to keep in mind initial price value.

Because when you decrease quantity (after increasing it), your code returns wrong result.

A more complete code here:

jQuery(document).ready(function($){

  // grab the price
  var initial_price = $('[itemprop="price"]').attr('content');

  $('.qty').on('change',function(){
     var total_price = initial_price * this.value;
     console.log(initial_price, this.value, total_price);
  });

})

Also you need to format price before printing it on the page:

  • add currency symbol after (or before) price;
  • set count of decimals (e.g. $99.9 or $99.99) (you might use toFixed() method for this);
  • etc.

It depends from your task.

Hope it helps.

Upvotes: 0

Related Questions