How to add increment(plus +) and decrements(minus -) qty button on product detail page?
3 Answers
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>
-
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.– codigaOct 2, 2019 at 9:26
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
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
-
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. Jun 15, 2018 at 7:06