skip to Main Content

I have a variable product on WooCommerce with 2 variations
The variations are based on weight. One of them is 0.5 kg and the other one is 1 kg.
So I would like to change default quantify selector value and set the selector value based on selection on variation. For example, When user select variation 0.5 kg variation the quantify selector value start as 0.5 and when select 1 kg variation start as 1.

I have changed this code, but it is not working and when user click on 0.5 first the 0.5 appear on input quantity field, but it’s not increased 0.5 by 0.5.

Any help is appreciated.

Here is my code:

  function enqueue_custom_scripts() {
    wp_enqueue_script( 'custom-script', get_stylesheet_directory_uri() . '/js/custom-script.js', array( 'jquery' ), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_scripts' );

And my js code is:

(function($) {
    // Wait for the variation to be selected
    $(document).on('found_variation', function(event, variation) {
        // Get the selected variation weight
        var variationWeight = parseFloat(variation.weight);

        // Update the default quantity selector value based on the selected variation weight
        $('input[name="quantity"]').val(variationWeight);

        // Trigger a change event on the quantity selector to update the displayed value
        $('input[name="quantity"]').trigger('change');
    });
})(jQuery);

2

Answers


  1. Chosen as BEST ANSWER

    I've found the solution and hope will be useful for everyone who might have a problem like me.

    (function($) {
        // Store the initial quantity step
        var initialStep = parseFloat($('input[name="quantity"]').attr('step'));
    
        // Wait for the variation to be selected
        $(document).on('found_variation', function(event, variation) {
            // Get the selected variation weight
            var variationWeight = parseFloat(variation.weight);
    
            // Update the default quantity selector value based on the selected variation weight
            $('input[name="quantity"]').val(variationWeight);
    
            // Update the step value to match the selected variation weight
            $('input[name="quantity"]').attr('step', variationWeight);
    
            // Trigger a change event on the quantity selector to update the displayed value
            $('input[name="quantity"]').trigger('change');
        });
    
        // Reset the quantity step to its initial value when a different variation is selected
        $(document).on('reset_data', function() {
            $('input[name="quantity"]').attr('step', initialStep);
        });
    })(jQuery);
    

  2. This is based on your initial question content (that you changed multiple times).

    There is a much simpler approach, that will be easier and more integrated in default WooCommerce, using product variation weight as quantity step (and min quantity). The following code will also handle the quantity input field in cart.

    I have simplified the quantity step calculation in this code (if you need, you will be able easily to make your calculation in the first function).

    Important:

    • The variation price can only handle a price by kilo in your case.
    • The stock management will need some further improvements to handle stock based on weight.

    The code:

    // Utility function: calculated quantity step based on variation weight
    function variation_qty_step( $variation_weight = null, $variation = null ) {
        // Here there is not really any calculation
        return $variation_weight ? ( $variation_weight * 1 ) : 1;
    }
    
    // Product variations (define the min value)
    add_filter( 'woocommerce_available_variation', 'add_product_variation_quantity_step', 10, 3);
    function add_product_variation_quantity_step( $variation_data, $product, $variation ) {
        if( $variation_data['weight'] ) {
            // Get the quantity step based on variation weight
            $qty_qtep = variation_qty_step( $variation_data['weight'] );
            // Add Qty step as an available argument to the main variable product form
            $variation_data['min_qty'] = $variation_data['qty_step'] = $qty_qtep;
            // Add a label "by Kilo" to the variation price html
            $variation_data['price_html'] =  sprintf(
                '<span class="price">%s <em class="price-label">(%s)</em></span>',
                $variation->get_price_html(), __("by kilo", "woocommerce") 
            );
        }
        return $variation_data;
    }
    
    // Variable product: Use variation qty step
    add_action( 'woocommerce_after_variations_form', 'product_variation_quantity_input_js', 11 );
    function product_variation_quantity_input_js() {
        ?>
        <script type="text/javascript">
        jQuery( function($){
            var iniStep = $('.quantity input.qty').attr('step'),
                iniVal  = $('.quantity input.qty').val();
            $('form.variations_form').on('show_variation found_variation', function( event, data ){
                $('.quantity input.qty').attr('step', data.qty_step).val(data.qty_step);
            }).on('hide_variation', function(){
                $('.quantity input.qty').attr('step', iniStep).val(iniVal);
            });
        });
        </script>
        <?php
    }
    
    // Cart: handle product variation input quantity based on weight
    add_filter( 'woocommerce_quantity_input_args', 'cart_variation_quantity_input_args', 10, 2 );
    function cart_variation_quantity_input_args( $args, $product ){
        if( is_cart() && $product->is_type('variation') && $product->get_weight() ) {
            $args['step'] = $args['min_value'] = $product->get_weight();
        }
        return $args;
    }
    
    // Cart: add "by kg" label to the cart unit price
    add_action( 'woocommerce_cart_item_price', 'filter_cart_displayed_price', 10, 2 );
    function filter_cart_displayed_price( $price, $cart_item ) {
        if ( $cart_item['data']->is_type('variation') &&  $cart_item['data']->get_weight() ) {
            return $price . ' <em class="price-label">(' . __("by kilo", "woocommerce") . ')</em>';
        }
        return $price;
    }
    
    // Enable decimal quantities (in frontend and backend)
    remove_filter('woocommerce_stock_amount', 'intval');
    add_filter('woocommerce_stock_amount', 'floatval');
    

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

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