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.
Contents
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
1 2 3 4 5 6 7 8 9 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
<?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!