Hello Magento Friends,
In this blog, we will discuss about adding quantity increment and decrement on the Magento 2 Category Page.
By default, Magento 2 allows customers to update product quantities only on the product detail page. However, enabling quantity adjustment directly on the category page streamlines the purchasing process, saving customers time and effort. In this blog post, we’ll explore how to implement this feature in Magento 2.
Why Add Quantity Increment and Decrement on Category Page?
Imagine a scenario where a customer is browsing through different products in a category and wants to purchase multiple quantities of a particular item. In the traditional setup, the customer would have to navigate to the product detail page, adjust the quantity, and then return to the category page to continue browsing. This process can be cumbersome and may lead to frustration, especially for customers with a long shopping list.
By integrating quantity increment and decrement buttons directly on the category page, customers can effortlessly adjust the quantity of each product without leaving the page. This not only improves the overall user experience but also encourages impulse purchases and increases conversion rates.
Using the Magento 2 Quantity Increment & Decrement Buttons Extension, you can show the quantity increment decrement button on various places within the customer’s shopping journey.
Steps to Add Quantity Increment and Decrement on Category Page in Magento 2:
Step 1: First, we need to create a “catalog_category_view.xml“ file to override list.phtml file at the following path.
app\code\Vendor\Extension\view\frontend\layout\catalog_category_view.xml
Then add the code as follows
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="category.products.list"> <action method="setTemplate"> <argument name="template" xsi:type="string">Vender_Extension::product/list.phtml</argument> </action> </referenceBlock> </body> </page>
Step 2: After that, we need to create a “list.phtml” file inside our extension at the following path.
app\code\Vendor\Extension\view\frontend\templates\product\list.phtml
And add the code as given below
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ use Magento\Framework\App\Action\Action; ?> <?php /** * Product list template * * @var $block \Magento\Catalog\Block\Product\ListProduct * @var \Magento\Framework\Escaper $escaper * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */ ?> <?php $_productCollection = $block->getLoadedProductCollection(); /** @var \Magento\Catalog\Helper\Output $_helper */ $_helper = $block->getData('outputHelper'); ?> <?php if (!$_productCollection->count()): ?> <div class="message info empty"> <div><?= $escaper->escapeHtml(__('We can\'t find products matching the selection.')) ?></div> </div> <?php else: ?> <?= $block->getToolbarHtml() ?> <?= $block->getAdditionalHtml() ?> <?php if ($block->getMode() === 'grid') { $viewMode = 'grid'; $imageDisplayArea = 'category_page_grid'; $showDescription = false; $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW; } else { $viewMode = 'list'; $imageDisplayArea = 'category_page_list'; $showDescription = true; $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::FULL_VIEW; } /** * Position for actions regarding image size changing in vde if needed */ $pos = $block->getPositioned(); ?> <div class="products wrapper <?= /* @noEscape */ $viewMode ?> products-<?= /* @noEscape */ $viewMode ?>"> <ol class="products list items product-items"> <?php /** @var $_product \Magento\Catalog\Model\Product */ ?> <?php foreach ($_productCollection as $_product): ?> <li class="item product product-item"> <div class="product-item-info" id="product-item-info_<?= /* @noEscape */ $_product->getId() ?>" data-container="product-<?= /* @noEscape */ $viewMode ?>"> <?php $productImage = $block->getImage($_product, $imageDisplayArea); if ($pos != null) { $position = 'left:' . $productImage->getWidth() . 'px;' . 'top:' . $productImage->getHeight() . 'px;'; } ?> <?php // Product Image ?> <a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>" class="product photo product-item-photo" tabindex="-1"> <?= $productImage->toHtml() ?> </a> <div class="product details product-item-details"> <?php $_productNameStripped = $block->stripTags($_product->getName(), null, true); ?> <strong class="product name product-item-name"> <a class="product-item-link" href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>"> <?=/* @noEscape */ $_helper->productAttribute($_product, $_product->getName(), 'name')?> </a> </strong> <?= $block->getReviewsSummaryHtml($_product, $templateType) ?> <?= /* @noEscape */ $block->getProductPrice($_product) ?> <?= $block->getProductDetailsHtml($_product) ?> <div class="product-item-inner"> <div class="product actions product-item-actions"> <div class="actions-primary"> <?php if ($_product->isSaleable()):?> <?php $postParams = $block->getAddToCartPostParams($_product); ?> <form data-role="tocart-form" data-product-sku="<?= $escaper->escapeHtml($_product->getSku()) ?>" action="<?= $escaper->escapeUrl($postParams['action']) ?>" data-mage-init='{"catalogAddToCart": {}}' method="post"> <?php $options = $block->getData('viewModel')->getOptionsData($_product); ?> <?php foreach ($options as $optionItem): ?> <input type="hidden" name="<?= $escaper->escapeHtml($optionItem['name']) ?>" value="<?= $escaper->escapeHtml($optionItem['value']) ?>"> <?php endforeach; ?> <input type="hidden" name="product" value="<?= /* @noEscape */ $postParams['data']['product'] ?>"> <input type="hidden" name="<?= /* @noEscape */ Action::PARAM_NAME_URL_ENCODED ?>" value="<?= /* @noEscape */ $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>"> <!--- Quantity Increment and Decrement code start --> <div class="popup_control"> <div class="qty-minus"> <span class="btn-qty minus quantity-minus" href="#">-</span></div> <input type="number" name="qty" style="width: 41px;text-align: center;height: 34px;" id="qty_<?php echo $_product->getId() ?>" maxlength="12" value="1" title="<?php /* @escapeNotVerified */echo __('Qty') ?>" class="qty-default input-text qty"/> <div class="qty-plus"> <span class="btn-qty plus quantity-plus" href="#">+</span></div> </div> <!--- Quantity Increment and Decrement code end --> <?= $block->getBlockHtml('formkey') ?> <button type="submit" title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>" class="action tocart primary" disabled> <span><?= $escaper->escapeHtml(__('Add to Cart')) ?></span> </button> </form> <?php else:?> <?php if ($_product->isAvailable()):?> <div class="stock available"> <span><?= $escaper->escapeHtml(__('In stock')) ?></span></div> <?php else:?> <div class="stock unavailable"> <span><?= $escaper->escapeHtml(__('Out of stock')) ?></span></div> <?php endif; ?> <?php endif; ?> </div> <?= ($pos && strpos($pos, $viewMode . '-primary')) ? /* @noEscape */ $secureRenderer->renderStyleAsTag( $position, 'product-item-info_' . $_product->getId() . ' div.actions-primary' ) : '' ?> <div data-role="add-to-links" class="actions-secondary"> <?php if ($addToBlock = $block->getChildBlock('addto')): ?> <?= $addToBlock->setProduct($_product)->getChildHtml() ?> <?php endif; ?> </div> <?= ($pos && strpos($pos, $viewMode . '-secondary')) ? /* @noEscape */ $secureRenderer->renderStyleAsTag( $position, 'product-item-info_' . $_product->getId() . ' div.actions-secondary' ) : '' ?> </div> <?php if ($showDescription): ?> <div class="product description product-item-description"> <?= /* @noEscape */ $_helper->productAttribute( $_product, $_product->getShortDescription(), 'short_description' ) ?> <a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>" title="<?= /* @noEscape */ $_productNameStripped ?>" class="action more"><?= $escaper->escapeHtml(__('Learn More')) ?></a> </div> <?php endif; ?> </div> </div> </div> <?= ($pos && strpos($pos, $viewMode . '-actions')) ? /* @noEscape */ $secureRenderer->renderStyleAsTag( $position, 'product-item-info_' . $_product->getId() . ' div.product-item-actions' ) : '' ?> </li> <?php endforeach; ?> </ol> </div> <?= $block->getChildBlock('toolbar')->setIsBottom(true)->toHtml() ?> <?php // phpcs:ignore Magento2.Legacy.PhtmlTemplate ?> <?php endif; ?> <script> require(['jquery'], function ($) { $(".qty-default").on("keyup", function() { var id = $(this).attr('id'); var beforeele = '#' + id; var newqtyupdate = '#custom_' + id; $(newqtyupdate).val($(beforeele).val()); }); $('.qty-plus').click(function () { // $('.qty-default').val(Number($('.qty-default').val()) + 1); var currentQTY = parseInt($(this).parent().parent().find(".qty-default").val()); currentQTY = currentQTY + 1; $(this).parent().parent().find(".qty-default").val(currentQTY); var idcustom = $(this).parent().parent().find(".qty-default").attr('id'); var newqtyupdate = '#custom_' + idcustom; var beforeele = '#' + idcustom; $(newqtyupdate).val($(beforeele).val()); }); $('.qty-minus').click(function () { var currentQTY = parseInt($(this).parent().parent().find(".qty-default").val()); currentQTY = currentQTY - 1; if (currentQTY > 0) { $(this).parent().parent().find(".qty-default").val(currentQTY); var idcustom = $(this).parent().parent().find(".qty-default").attr('id'); var newqtyupdate = '#custom_' + idcustom; var beforeele = '#' + idcustom; $(newqtyupdate).val($(beforeele).val()); } }); }); </script>
Output:
Conclusion:
Incorporating quantity increment and decrement functionality on the category page can significantly enhance the shopping experience for Magento 2 store customers. Previously, I have shared a solution for Adding the Quantity Increment & Decrement Button to the Product page in Magento 2.
Share the tutorial with your friends and stay in touch with us for more.
Happy Coding!