skip to Main Content

With WooCommerce last version, I need to display on product page the weight of the variation chosen in short description and I would like to display the total weight just beside the add to cart button when you choose more than 1 quantity.

For example: I select 4 quantity. Unit weight is 4 kgs. I need to display: "The total weight is 16kgs".

This code works well if the general product has a weight, but it doesn’t works with variations weight:

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>', __('Totale Prodotto:','woocommerce'),'<span class="price">' . $product->get_price() . '</span>');
    echo sprintf('<div id="product_total_weight" style="margin-bottom:20px;">%s %s</div>', __('Totale Peso:','woocommerce'),'<span class="weight">' . $product->get_weight() . '</span>');
    
    ?>
        <script>
            jQuery(function($) {
                var price = <?php echo $product->get_price(); ?>, 
                    currency = '<?php echo get_woocommerce_currency_symbol(); ?>';
                    
                var weight = <?php echo $product->get_weight(); ?>;

                $('[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) );
                        
                        var weight_total = parseFloat(weight * this.value);
                        
                        $('#product_total_weight .weight').html( weight_total.toFixed(2) + ' kg');                      
                    }
                });
            });
        </script>
    <?php
}
add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 );

2

Answers


  1. Chosen as BEST ANSWER

    I see a quantity_input.php file in the theme i use, maybe it's here that quantity input is reset.

    if ( $max_value && $min_value === $max_value ) {
    ?>
    <div class="quantity hidden">
        <input type="hidden" id="<?php echo esc_attr( $input_id ); ?>" class="qty" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $min_value ); ?>" />
    </div>
    <?php
    } else {
    /* translators: %s: Quantity. */
    $labelledby = ! empty( $args['product_name'] ) ? sprintf( esc_html__( '%s quantity', 'essentials' ), strip_tags( $args['product_name'] ) ) : '';
    ?>
    <div class="quantity mr-2 pix-px-10 bg-white rounded-lg shadow-sm d-inline-block">
        <label class="screen-reader-text sr-only" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity', 'essentials' ); ?></label>
        <a href="#" class="minus d-inline-block text-body-default" >-</a>
        <input
            type="number"
            id="<?php echo esc_attr( $input_id ); ?>"
            class="input-text qty text form-control shadow-0 d-inline-block"
            step="<?php echo esc_attr( $step ); ?>"
            min="<?php echo esc_attr( $min_value ); ?>"
            max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
            name="<?php echo esc_attr( $input_name ); ?>"
            value="<?php echo esc_attr( $input_value ); ?>"
            title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'essentials' ); ?>"
    
            size="4"
            pattern="<?php echo esc_attr( $pattern ); ?>"
            inputmode="<?php echo esc_attr( $inputmode ); ?>"
            aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
            <a href="#" class="plus d-inline-block text-body-default" >+</a>
    </div>
    <?php
    }
    

    And i also have a frontend.js file in plugin folder :

    jQuery( function ( $ ) {

        if ( ywmmq.variations ) {
    
            $( document ).on(
                'found_variation',
                function () {
    
                    var product_id   = parseInt( $( '.single_variation_wrap .product_id, .single_variation_wrap input[name="product_id"]' ).val() ),
                        variation_id = parseInt( $( '.single_variation_wrap .variation_id, .single_variation_wrap input[name="variation_id"]' ).val() );
    
                    if ( ! isNaN( product_id ) && ! isNaN( variation_id ) ) {
    
                        get_variation_rules( product_id, variation_id );
    
                    }
    
                }
            );
    
        }
    
        function get_variation_rules( product_id, variation_id ) {
    
            var container       = $( '.ywmmq-rules-wrapper' ),
                variations_form = $( '.single_variation_wrap' ),
                raq_button      = $( '.add-request-quote-button' );
    
            if ( variations_form.is( '.processing' ) ) {
                return false;
            }
    
            variations_form.addClass( 'processing' );
            raq_button.addClass( 'disabled' );
            variations_form.block(
                {
                    message   : null,
                    overlayCSS: {
                        background: '#fff',
                        opacity   : 0.6
                    }
                }
            );
    
            $.ajax(
                {
                    type    : 'POST',
                    url     : ywmmq.ajax_url,
                    data    : {
                        action      : 'ywmmq_get_rules',
                        product_id  : product_id,
                        variation_id: variation_id
                    },
                    success : function ( response ) {
    
                        if ( response.status === 'success' ) {
    
                            container.html( response.rules );
    
                            if ( parseInt( response.limits.max ) !== 0 ) {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).attr( 'max', response.limits.max );
    
                            } else {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).removeAttr( 'max' );
    
                            }
    
                            if ( parseInt( response.limits.min ) !== 0 ) {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).attr( 'min', response.limits.min ).val( response.limits.min );
    
                            } else {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).attr( 'min', 1 ).val( 1 );
    
                            }
    
                            if ( parseInt( response.limits.step ) !== 0 ) {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).attr( 'step', response.limits.step );
    
                            } else {
    
                                $( '.single_variation_wrap .quantity input[name="quantity"]' ).attr( 'step', 1 ).val( 1 );
    
                            }
    
                            $( document ).trigger( 'ywmmq_additional_operations', [response.limits.min] );
    
                        } else {
    
                            container.html();
    
                        }
    
                        variations_form.removeClass( 'processing' ).unblock();
                        raq_button.removeClass( 'disabled' );
    
                    },
                    dataType: 'json'
                }
            );
    
            return false;
    
        }
    
        $( document ).on(
            'yith_wcpb_found_variation_after',
            function ( event, form, variation ) {
    
                if ( form.is( '.processing' ) ) {
                    return false;
                }
    
                form.addClass( 'processing' );
                form.block(
                    {
                        message   : null,
                        overlayCSS: {
                            background: '#fff',
                            opacity   : 0.6
                        }
                    }
                );
    
                $.ajax(
                    {
                        type    : 'POST',
                        url     : ywmmq.ajax_url,
                        data    : {
                            action      : 'ywmmq_get_rules',
                            product_id  : form.data( 'product_id' ),
                            variation_id: form.find( '.variation_id' ).val()
                        },
                        success : function ( response ) {
    
                            if ( response.status === 'success' ) {
    
                                if ( parseInt( response.limits.max ) !== 0 ) {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).attr( 'max', response.limits.max );
    
                                } else {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).removeAttr( 'max' );
    
                                }
    
                                if ( parseInt( response.limits.min ) !== 0 ) {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).attr( 'min', response.limits.min ).val( response.limits.min );
    
                                } else {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).attr( 'min', 1 ).val( 1 );
    
                                }
    
                                if ( parseInt( response.limits.step ) !== 0 ) {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).attr( 'step', response.limits.step );
    
                                } else {
    
                                    form.find( '.yith-wcpb-bundled-quantity' ).attr( 'step', 1 ).val( 1 );
    
                                }
    
                            }
    
                            form.removeClass( 'processing' ).unblock();
    
                        },
                        dataType: 'json'
                    }
                );
    
            }
        )
    
    }
    );
    

  2. You can create a javascript object that will contain the necessary values based on the type of product.

    The idea is this:

    1. Create a PHP array with the product type and other necessary fields (price, currency and weight);
    2. Convert PHP array to Javascript object to use in script
    3. Based on the type of product, it obtains the price and weight of the product (if the product is variable, it obtains the values of the selected variation)

    In the previous function I used the variation slugs to determine which option was chosen. This method works only if the variable product has a single select.

    Thanks to @LoicTheAztec’s answer you find here:

    I figured I could get the value of the chosen variation id from the hidden input with the variation_id class.

    It will now also work with variable products that have more than one
    select options
    .

    I changed the function by splitting it in two.

    1. The first script adds the content to the product page (under the add to cart form).

    2. The second adds the script in the footer to handle changing values.

    So:

    // shows the total price and total weight based on the quantity entered
    add_action( 'woocommerce_single_product_summary', 'show_total_price_and_total_weight_by_quantity', 31 );
    function show_total_price_and_total_weight_by_quantity() {
        // create the divs that will contain the total price and total weight
        echo sprintf('<div id="product_total_price" style="display:none;margin-bottom:20px;">%s %s</div>', __('Totale Prodotto:','woocommerce'),'<span class="price"></span>');
        echo sprintf('<div id="product_total_weight" style="display:none;margin-bottom:20px;">%s %s</div>', __('Totale Peso:','woocommerce'),'<span class="weight"></span>');
    }
    
    // change the total price and total weight based on the quantity entered
    add_action( 'wp_footer', 'change_total_price_and_total_weight_by_quantity', 99 );
    function change_total_price_and_total_weight_by_quantity() {
        // only on the product page
        if ( ! is_product() ) {
            return;
        }
    
        global $product;
        
        // initializes the array that will contain the product data
        $product_data = array();
    
        // do divs need to be shown?
        $show = true;
    
        // gets the currency and unit of weight
        $currency = get_woocommerce_currency_symbol();
        $weight_unit = get_option('woocommerce_weight_unit');
    
        // if the product is simple
        if ( $product->is_type( 'simple' ) ) {
            // set the type of product
            $product_data['type']  = 'simple';
            // get simple product data
            $product_data['price'] = $product->get_price();
            $product_data['currency'] = $currency;
            $product_data['weight'] = $product->get_weight();
            $product_data['weight_unit'] = $weight_unit;
        }
    
        // if the product is variable
        if ( $product->is_type( 'variable' ) ) {
            // set the type of product
            $product_data['type']  = 'variable';
            // get the ids of the product variations
            $variation_ids = $product->get_children();
            foreach ( $variation_ids as $variation_id ) {
                // gets the object of the variation product
                $variation = wc_get_product( $variation_id );
                // gets product variation data
                $product_data['variation'][$variation_id]['price'] = $variation->get_price();
                $product_data['variation'][$variation_id]['currency'] = $currency;
                $product_data['variation'][$variation_id]['weight'] = $variation->get_weight();
                $product_data['variation'][$variation_id]['weight_unit'] = $weight_unit;
            }
            // hides the div
            $show = false;
        }
    
        // returns the JSON representation of a data
        $product_data_json = json_encode( $product_data );
    
        ?>
            <script>
                jQuery(function($) {
                    // create a javascript object with product data
                    <?php
                    echo "var productData = ". $product_data_json . ";";
                    if ( $show ) {
                        ?>
                        var product_total = parseFloat( productData.price * $('[name=quantity]').val());
                        $('#product_total_price .price').html( productData.currency + product_total.toFixed(2) );
                        var weight_total = parseFloat(productData.weight * $('[name=quantity]').val());
                        $('#product_total_weight .weight').html( weight_total.toFixed(2) + ' ' + productData.weight_unit);
                        $('#product_total_price').show();
                        $('#product_total_weight').show();
                        <?php
                    }
                    ?>
                    // when the quantity is changed or a product option is selected
                    jQuery('[name=quantity], table.variations select').on('change',function(){
                        // shows data based on product type
                        switch( productData.type ) {
                            case 'simple':
                                // update the fields
                                var product_total = parseFloat(productData.price * $(this).val());
                                $('#product_total_price .price').html( productData.currency + product_total.toFixed(2) );
                                var weight_total = parseFloat(productData.weight * $(this).val());
                                $('#product_total_weight .weight').html( weight_total.toFixed(2) + ' ' + productData.weight_unit);                      
                                break;
                            case 'variable':
                                // gets the id variation based on the options chosen
                                var variation_id = $('input.variation_id').val();
                                // if the variation id is valid and the current option is different from "Choose an option"
                                if ( parseInt( $('input.variation_id').val() ) > 0 && $('input.variation_id').val() != '' && $(this).find('option').filter(':selected').val() != '' ) {
                                    $('#product_total_price').show();
                                    $('#product_total_weight').show();
                                    // gets the object based on the selected variation
                                    var obj = productData.variation[variation_id];
                                    // update the fields
                                    var product_total = parseFloat(obj.price * $(this).val());
                                    $('#product_total_price .price').html( obj.currency + ' ' + product_total.toFixed(2) );
                                    var weight_total = parseFloat(obj.weight * $(this).val());
                                    $('#product_total_weight .weight').html( weight_total.toFixed(2) + ' ' + obj.weight_unit);
                                // otherwise it hides the divs
                                } else {
                                    $('#product_total_price').hide();
                                    $('#product_total_weight').hide();
                                }
                                break;
                        }
                    });
                });
            </script>
        <?php
    
    }
    

    The code has been tested and works. Add it to your active theme’s functions.php.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search