1

I use a script to change the qty in the product view page and in the shopping cart page but I have a problem. when I decrease the qty instead the latest value to be 0 is -1. How I can stop the decrease button to remain on the 0 value?

require([
    'jquery'
], function ($) {
    $(document).ready(function(){
        
         /********************* Qty Holder **************************/
        $(document).on("click", ".qtyplus", function(e) {
            // Stop acting like a button
            e.preventDefault();
            // Get its current value
            var currentVal = parseInt($(this).parents('.qty-changer').find('input.input-text.qty').val());

            // If is not undefined
            if (!isNaN(currentVal)) {
                // Increment
                $(this).parents('.qty-changer').find('input.input-text.qty').val(currentVal + 1);
                $(this).parents('.qty-changer').find('.update-cart-item').show();
            } else {
                // Otherwise put a 0 there
                $(this).parents('.qty-changer').find('input.input-text.qty').val(1);
            }
        });
        // This button will decrement the value till 0
        $(document).on("click", ".qtyminus", function(e) {
            // Stop acting like a button
            e.preventDefault();
            // Get the field name
            fieldName = $(this).attr('field');
            // Get its current value
            var currentVal = parseInt($(this).parents('.qty-changer').find('input.input-text.qty').val());

            // If it isn't undefined or its greater than 0

            if (!isNaN(currentVal) && currentVal >= 0) {
                // Decrement one
                $(this).parents('.qty-changer').find('input.input-text.qty').val(currentVal - 1);
                $(this).parents('.qty-changer').find('.update-cart-item').show();
            } else {
                // Otherwise put a 0 there
                $(this).parents('.qty-changer').find('input.input-text.qty').val(1);
            }
        }); 
        
        
        $(".qtyplus").unbind('click').click(function(){
            if($(this).parent().parent().children(".control").children("input.input-text.qty").is(':enabled')){
                $(this).parent().parent().children(".control").children("input.input-text.qty").val((+$(this).parent().parent().children(".control").children("input.input-text.qty").val() + 1) || 0);
                $(this).parent().parent().children(".control").children("input.input-text.qty").trigger('change');
                $(this).focus();
            }
        });
        $(".qtyminus").unbind('click').click(function(){
            if($(this).parent().parent().children(".control").children("input.input-text.qty").is(':enabled')){
                $(this).parent().parent().children(".control").children("input.input-text.qty").val(($(this).parent().parent().children(".control").children("input.input-text.qty").val() - 1 > 0) ? ($(this).parent().parent().children(".control").children("input.input-text.qty").val() - 1) : 0);
                $(this).parent().parent().children(".control").children("input.input-text.qty").trigger('change');
                $(this).focus();
            }
        });
    });
});

Thank you

3 Answers 3

2

You can add Inc/Dec button on PDP.

            <div class="field qty">
                <label class="label" for="qty"><span><?php /* @escapeNotVerified */
                        echo __('Qty') ?></span></label>
                <div class="control control-qty-cart">
                    <input type="number"
                           name="qty"
                           id="qty"
                           maxlength="12"
                           value="<?php /* @escapeNotVerified */
                           echo $block->getProductDefaultQty() * 1 ?>"
                           title="<?php /* @escapeNotVerified */
                           echo __('Qty') ?>" class="qty-default input-text qty"
                           data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                    />

                    <div class="control-qty">
                        <span class="quantity-controls quantity-plus">+</span>
                        <span class="quantity-controls quantity-minus">-</span>

                        <script type="text/javascript">
                            require([
                                'jquery'
                            ], function ($) {
                                $('.quantity-plus').click(function () {
                                    $('.qty-default').val(Number($('.qty-default').val()) + 1);
                                });

                                $('.quantity-minus').click(function () {
                                    var value = Number($('.qty-default').val()) - 1;
                                    if (value > 0) {
                                        $('.qty-default').val(value);
                                    }

                                });
                            });
                        </script>
                    </div>
                </div>
            </div>
1
  • thank you for your answer, there on my store I have grouped products and this code is not work, you have any idea why??
    – Robert
    Commented May 7, 2021 at 7:55
0

I suspect it's because of this code:

if (!isNaN(currentVal) && currentVal >= 0) {
            // Decrement one
            $(this).parents('.qty-changer').find('input.input-text.qty').val(currentVal - 1);
            $(this).parents('.qty-changer').find('.update-cart-item').show();
        } else {
            // Otherwise put a 0 there
            $(this).parents('.qty-changer').find('input.input-text.qty').val(1);
        }

So currentVal may = 0, and then you are subtracting 1 from it here:

.val(currentVal - 1)

If this is the case you need to alter your logic, maybe change currentVal >= 0 to currentVal > 0?

3
  • thank you, if I change as you said: currentVal > 0 instead of -1 there is 1, I need to be 0
    – Robert
    Commented May 5, 2021 at 10:45
  • Add another else statement to handle currentVal being 0.
    – Ben Crook
    Commented May 5, 2021 at 11:15
  • 1
    I recommend using Vrajesh's solution, yours is unnecessarily complex just to increment and decrement the quantity.
    – Ben Crook
    Commented May 5, 2021 at 11:16
0

Here is a small solution magento 2.4.3 for the cart page:

Here it is so that the buttons -/+ per click updates the data. But additionally with the entry in the input field an update button appears which updates the quantity by clicking on it.

copy:

vendor/magento/module-checkout/view/frontend/templates/cart/item/default.phtml

to your design folder:

app/design/{your_theme}/Magento_Checkout/templates/cart/item/default.phtml

Change line 97:

<td class="col qty" data-th="<?= $block->escapeHtml(__('Qty')) ?>">

to:

<td class="col qty" data-th="<?= $block->escapeHtml(__('Qty')) ?>" data-id="<?= $block->escapeHtmlAttr($_item->getId()) ?>">

Change Line 99-115:

<div class="control qty">
    <label for="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty">
        <span class="label"><?= $block->escapeHtml(__('Qty')) ?></span>
        <input id="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty"
               name="cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]"
               data-cart-item-id="<?= $block->escapeHtmlAttr($_item->getSku()) ?>"
               value="<?= $block->escapeHtmlAttr($block->getQty()) ?>"
               type="number"
               size="4"
               step="any"
               title="<?= $block->escapeHtmlAttr(__('Qty')) ?>"
               class="input-text qty"
               data-validate="{required:true,'validate-greater-than-zero':true}"
               data-item-qty="<?= $block->escapeHtmlAttr($block->getQty()) ?>"
               data-role="cart-item-qty"/>
    </label>
</div>

to:

<div class="control qty" data-mage-init='{"Magento_Checkout/js/update_qty": {}}'>
    <label for="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty">
        <span class="label"><?= $block->escapeHtml(__('Qty')) ?></span>
        <a class="qty -minus">-</a>
        <input id="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty"
               name="cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]"
               data-cart-item-id="<?= $block->escapeHtmlAttr($_item->getSku()) ?>"
               value="<?= $block->escapeHtmlAttr($block->getQty()) ?>"
               type="number"
               size="4"
               step="any"
               title="<?= $block->escapeHtmlAttr(__('Qty')) ?>"
               class="input-text qty"
               data-validate="{required:true,'validate-greater-than-zero':true}"
               data-item-qty="<?= $block->escapeHtmlAttr($block->getQty()) ?>"
               data-role="cart-item-qty"/>
        <a class="qty -plus">+</a>
    </label>
    <a class="hidden update-btn cursor-pointer" id="update-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty">
        <span><?= $block->escapeHtmlAttr(__('Update')) ?></span>
    </a>
</div>

add a new file to your design folder: app/design/{your_theme}/Magento_Checkout/web/js/

define([
    'jquery',
    'Magento_Checkout/js/action/get-totals',
    'Magento_Customer/js/customer-data'
], function ($, getTotalsAction, customerData) {
    $(document).ready(function () {
        $(document).on('click', 'a.qty', function () {
            var $this = $(this),
                productId = $(this).parents('td').data('id'),
                updateInput = $("#cart-" + productId + "-qty"),
                currentQty = updateInput.val();

            if ($this.hasClass('-plus')) {
                var newAdd = parseInt(currentQty) + parseInt(1);
                updateInput.val(newAdd);
                ajaxUpdate();
            } else if ($this.hasClass('-minus')) {
                if (currentQty > 1) {
                    var newAdd = parseInt(currentQty) - parseInt(1);
                    updateInput.val(newAdd);
                }
                ajaxUpdate();
            }

        });
        $(document).on('change', 'input.input-text.qty', function () {
            var $this = $(this),
                productId = $(this).parents('td').data('id'),
                updateButton = $("#update-" + productId + "-qty");

            updateButton.show().removeClass('hidden').addClass('visible');
            $(updateButton).on('click', function () {
                ajaxUpdate();
            });
        });

        function ajaxUpdate() {
            var form = $('form#form-validate.form-cart');
            $.ajax({
                url: form.attr('action'),
                type: "POST",
                data: form.serialize(),
                showLoader: true,
                cache: false,
                success: function (res) {
                    var parsedResponse = $.parseHTML(res),
                        result = $(parsedResponse).find("#form-validate.form-cart"),
                        sections = ['cart'];

                    form.replaceWith(result);

                    // The mini cart reloading
                    customerData.reload(sections, true);

                    // The totals summary block reloading
                    var deferred = $.Deferred();
                    getTotalsAction([], deferred);
                },
                error: function (xhr, status, error) {
                    var err = eval("(" + xhr.responseText + ")");
                    console.log(err.Message);
                }
            });
            return true;
        };
    });
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.