WooCommerce Custom Quantity with variations

Viewed 24

I tried to use JS code for custom quantity with variations for WC
When variations changed - qty does not works right
Mistake step or value
Maybe reason in "show_variation" event

Link to test page

Please help me find and correct mistakes in this code

PHP

    <div class="quantity-button quantity-down">&minus;</div>
    <input
        type="number"
        id="<?php echo esc_attr( $input_id ); ?>"
        class="<?php echo esc_attr( join( ' ', (array) $classes ) ); ?>"
        step="<?php echo esc_attr( $step ); ?>"
        min="<?php echo esc_attr( $min_value ); ?>"
        max="<?php echo esc_attr( 0 < $max_value ? $max_value : 1 ); ?>"
        name="<?php echo esc_attr( $input_name ); ?>"
        value="<?php echo esc_attr( $input_value ); ?>"
        title="<?php _e( 'Кількість', AGDS_THEME_TD ) ?>"
        size="4"
        placeholder="<?php echo esc_attr( $placeholder ); ?>"
        inputmode="<?php echo esc_attr( $inputmode ); ?>"
        autocomplete="<?php echo esc_attr( isset( $autocomplete ) ? $autocomplete : 'on' ); ?>"
    />
    <div class="quantity-button quantity-up">&plus;</div>

JS

    var quantityCustom = () => {
    jQuery(".quantity").each(function () {
        var quantity = jQuery(this),
            input = quantity.find('input[type="number"]'),
            btnUp = quantity.find(".quantity-up"),
            btnDown = quantity.find(".quantity-down"),
            min = input.attr("min") !== '' ? Number(input.attr("min")) : 0,
            max = input.attr("max") !== '' ? Number(input.attr("max")) : 999,
            oldValue = parseFloat(input.val());

        btnUp.click(function (e) {
            e.preventDefault()
            if (oldValue >= max) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue + 1;
            }
            input.val(newVal);
            input.trigger("change");
        });

        btnDown.click(function (e) {
            e.preventDefault()
            if (oldValue <= min) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue - 1;
            }
            input.val(newVal);
            input.trigger("change");
        });
    })

}

$(document).on('show_variation', function (e, variation) {
    quantityCustom()
})
1 Answers

The problem is in your JS. It's keeping the old value as 1 and hence the quantity doesn't work or work till 2 only. You need to get the old value when it is clicked and not when the page is loaded.

Here's a corrected version of the same, but it can be much better as well:

    var quantityCustom = () => {
    jQuery(".quantity").each(function () {
        var quantity = jQuery(this),
        btnUp = quantity.find(".quantity-up"),
        btnDown = quantity.find(".quantity-down");
        
        
        btnUp.click(function (e) {
            e.preventDefault();
            var input = quantity.find('input[type="number"]'),
            min = input.attr("min") !== '' ? Number(input.attr("min")) : 0,
            max = input.attr("max") !== '' ? Number(input.attr("max")) : 999,
            oldValue = parseFloat(input.val());

            
            if (oldValue >= max) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue + 1;
            }
            input.val(newVal);
            input.trigger("change");
        });

        btnDown.click(function (e) {
            e.preventDefault();
            var input = quantity.find('input[type="number"]'),
            min = input.attr("min") !== '' ? Number(input.attr("min")) : 0,
            max = input.attr("max") !== '' ? Number(input.attr("max")) : 999,
            oldValue = parseFloat(input.val());

            if (oldValue <= min) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue - 1;
            }
            input.val(newVal);
            input.trigger("change");
        });
    })

}

$(document).on('show_variation', function (e, variation) {
    quantityCustom()
})

I personally don't like repeating the same code again and again but in your case, I had this change as the simplest. It should resolve your issue.

Related