5

How to add increment(plus +) and decrements(minus -) qty button on product detail page?

enter image description here

6

You can implement this with UI Components

1) Configure your requirejs-config.js to define your js module: (app/design/frontend/<vendor>/<theme>/Magento_Catalog/).

var config = {
    map: {
        '*': {
            'qty-counter': 'Magento_Catalog/js/qty-counter'
        }
    }
};

2) Copy and change template from vendor/magento/module-catalog/view/frontend/templates/product/view/addtocart.phtml to your theme app/design/frontend/<vendor>/<theme>/Magento_Catalog/templates/product/view/

...
<div class="box-tocart">
    <div class="fieldset">
        <?php if ($block->shouldRenderQuantity()): ?>
        <div class="field qty">
            <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Quantity:') ?></span></label>
            <div id="custom-qty" class="control" data-bind="scope: 'qty-counter'">
                <!-- ko template: getTemplate() --><!-- /ko -->
                <script type="text/x-magento-init">
                    {
                        "#custom-qty": {
                            "Magento_Ui/js/core/app": {
                                "components": {
                                    "qty-counter": {
                                        "component": "qty-counter",
                                        "config": {
                                            "qty": <?php echo $block->getProductDefaultQty() * 1 ?>,
                                            "dataValidate": <?php echo json_encode($block->getQuantityValidators()) ?>
                                        }
                                    }
                                 }
                            }
                        }
                    }
                </script>
            </div>
        </div>
        <?php endif; ?>
        <div class="actions">
            <button type="submit"
                    title="<?php /* @escapeNotVerified */ echo $buttonTitle ?>"
                    class="action primary tocart"
                    id="product-addtocart-button">
                <span><?php /* @escapeNotVerified */ echo $buttonTitle ?></span>
            </button>
            <?php echo $block->getChildHtml('', true) ?>
        </div>
    </div>
</div>
...

3) Add your js module

'use strict';

define([
    'ko',
    'uiElement'
], function (ko, Element) {
    return Element.extend({
        defaults: {
            template: 'Magento_Catalog/input-counter'
        },

        initObservable: function () {
            this._super()
                .observe('qty');

            return this;
        },

        getDataValidator: function() {
            return JSON.stringify(this.dataValidate);
        },

        decreaseQty: function() {
            var qty;

            if (this.qty() > 1) {
                qty = this.qty() - 1;
            } else {
                qty = 1;
            }

            this.qty(qty);
        },

        increaseQty: function() {
            var qty = this.qty() + 1;

            this.qty(qty);
        }
    });
});

4) Add html template

<div class="input-group">
    <span class="input-group__addon">
        <button click="decreaseQty" class="input-group__button input-group__button--decrease">
            <span class="input-group__icon input-group__icon--decrease"></span>
        </button>
    </span>
    <input data-bind="value: qty(), attr: {'data-validate': getDataValidator(), 'title': $t('Qty')}"
           type="number"
           name="qty"
           id="qty"
           maxlength="12"
           class="input-group__input" />
    <span class="input-group__addon">
        <button click="increaseQty" class="input-group__button input-group__button--increase">
            <span class="input-group__icon input-group__icon--increase"></span>
        </button>
    </span>
</div>
| improve this answer | |
  • Good solution, which generally works for me. But I have a problem with the validation (min, max). I have to modify this validation within my block class (hence in php), which works. But on the frontend, the validation-function validate-item-quantity is not triggered. – codiga Oct 2 '19 at 9:26
1

You can add Quantity Increment and Decrement Button in Magento 2 with KnockoutJS. Create a custom module:

Configure Module

Configure your module by creating a module.xml file in app/code/Magenticians/Mymodule/etc.Add the following code in it:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magenticians_Mymodule" setup_version="1.0.0"></module>
</config>

Go to vendor/magento/module-catalog/view/frontend/templates/product/view from the root directory of your store and copy addtocart.phtml to your own module app/code /Magenticians/Mymodule/view/frontend/templates/catalog/product/view. The addtocart.phtml file will looks like this:

<?php $_product = $block->getProduct(); ?>
<?php $buttonTitle = __('Add to Cart'); ?>
<?php if ($_product->isSaleable()): ?>
<div class="box-tocart">
   <div class="fieldset">
       <?php if ($block->shouldRenderQuantity()): ?>
       <div class="field qty">
           <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label>
           <div class="control">
               <input type="number"
                      name="qty"
                      id="qty"
                      maxlength="12"
                      value="<?php /* @escapeNotVerified */ echo $block->getProductDefaultQty() * 1 ?>"
                      title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty"
                      data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                      />
           </div>
       </div>
       <?php endif; ?>
       <div class="actions">
           <button type="submit"
                   title="<?php /* @escapeNotVerified */ echo $buttonTitle ?>"
                   class="action primary tocart"
                   id="product-addtocart-button">
               <span><?php /* @escapeNotVerified */ echo $buttonTitle ?></span>
           </button>
           <?php echo $block->getChildHtml('', true) ?>
       </div>
   </div>
</div>
<?php endif; ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "Magento_Catalog/product/view/validation": {
               "radioCheckboxClosest": ".nested"
           }
       }
   }
</script>
<?php if (!$block->isRedirectToCartEnabled()) : ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "catalogAddToCart": {
               "bindSubmit": false
           }
       }
   }
</script>
<?php endif; ?>

Follow this tutorial

| improve this answer | |
  • thanks, i don't want to create new module. – Chirag Patel Jun 14 '18 at 13:16
1

I have a simple solution that involves 1 template to be changed and a mixin to be created with 4 lines of jQuery

the mixin js code is:

define(['jquery'], function ($) {
    'use strict';

    return function (addToCart) {
        $('#minusQty').click(function () {
            $('#qty').val(parseInt($('#qty').val())-1);
        });

        $('#addQty').click(function () {
            $('#qty').val(parseInt($('#qty').val())+1);
        });

        return addToCart;
    }
});

and the template to edit is product/view/addtocart.phtml

I have an example at: https://bitbucket.org/magstaging/productdetailqtywidget

| improve this answer | |
  • Thanks, As i mentioned in above comment i don't want to add any external module or widget in my code. i want to build this functionality within code. – Chirag Patel Jun 15 '18 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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