Improving the WooCommerce Grouped Products Layout

Improving the WooCommerce Grouped Products Layout

7th April. Posted in Code Snippets, jQuery, Tutorials, WordPress.

WooCommerce is one of the best eCommerce platforms for WordPress and it’s very flexible. One of the features it provides is ‘grouped products’ – the ability to have a generic product as a parent which has a number of other related products to choose from on the product page.

On the project I was working on, this meant that we had a Product for Shakes and a number of grouped products – Strawberry shake, Chocolate shake, Vanilla shake etc. Each grouped product could have it’s own price set and you can optionally link to the grouped products individual page.

For the project I was working on, I wanted users to be able to make all their selections on the main product page and see the total cost of the items they have selected right away, which would be a far better experience than having to add your items and click the ‘add to cart’ button before you know what the total cost is. I was surprised to find that WooCommerce doesn’t provide that functionality by default so I needed to make some tweaks to my theme…

Changing the WooCommerce Template File

JavaScript would be needed to get the values from the input boxes and multiply each one by the price of that item, but first I needed a way to get the products price and make it available for my JavaScript to grab hold of. WooCommerce provides a great templating system where you simply create a ‘woocommerce’ folder in your themes root directory and copy the corresponding template file from the WooCommerce plugin into the directory (keeping the same folder structure too). Anything in your woocommerce folder will override the file provided by the plugin.

I decided the best way to get the price of each item in my JavaScript would be to output the price in a data attribute on the container for each grouped product. That would allow me to loop through each input box, get the parent with the data attribute attached and then get the price.

The template file that needs to be changed is called grouped.php and lives within the WooCommerce plugin folder in this location: templates > single-product > add-to-cart > grouped.php.

I copied this file and pasted it into my ‘woocommerce’ folder, creating the same folder structure as you can see here:


Then I opened up grouped.php and changed the parent container of the input boxes from this:


to this:

<tr class="grouped-product-item" data-price="<?php echo $product->get_price() ?>">

When I refreshed my product page and inspected the element I could see that the parent of each input was now displaying the price of the item (without currency) in the ‘data-price’ attribute and I add a new CSS class on the table row that I could use. Awesome! Time for JavaScript.

The JavaScript

I placed the following code in my functions file. The code calls the function ‘woocommerce_total_product_price’ using a WooCommerce action.

add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 ); 
function woocommerce_total_product_price() { 
    global $woocommerce, $product; 
    echo '<div id="product-total-price">'; 
        _e('Total Cost: ','woocommerce'); 
        echo '<span class="currency">' . get_woocommerce_currency_symbol() . '</span><span class="price"></span>'; 
        echo '</div>'; 
        var current_cart_total = <?php echo $woocommerce->cart->cart_contents_total; ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>'; 
        $('.input-text.qty, .quantity_select .qty').on('change',function(){ 
            var overall_total = 0; 
            $('.input-text.qty, .quantity_select .qty').each(function(){ 
                var price = $(this).parents('.grouped-product-item').data('price'); 
                var items = $(this).val(); 
                var total = price * items; 
                overall_total = overall_total + total; 
            if ( overall_total > 0 ) { 
                $('#product-total-price .price').html( overall_total.toFixed(2)); 
            else { 
                $('#product-total-price .price').html('0'); } 
<?php }

All the code does is output some HTML as a container for the total cost which is initially hidden in CSS. The JavaScript (jQuery) watches for a click on the input box and then grabs the price of the product that was just added / removed by looking for the parent with the data-price attribute that I added to grouped.php before. This is the part of the JavaScript that does that:

var price = $(this).parents('.grouped-product-item').data('price'); 

Then I did a calculation multiplying the value of each input with it’s price to give me an overall total when each input value is changed.

Finally I checked if the overall total was greater than 0 and faded the container in if it was so the user can see the overall total after any values are changed.

I also added some basic CSS changes to tidy things up. The grouped product layout is pretty poor by default. Here’s what my theme looked like after those changes:


Hopefully this will be useful if you are using WooCommerce grouped products and you would like a more user friendly experience.