Here we learn, How to Update Item Quantity in Minicart Magento2
1. Add custom controller to the customer data section, so when quantity will change then, it will update minicart automatically.
This is because when any ajax request get complete, then the Magento looks for the section to be update.
you can see in this file: Magento/Customer/view/frontend/web/js/customer-data.js
/** * Events listener */ $(document).on('ajaxComplete', function (event, xhr, settings) { var sections, redirects; if (settings.type.match(/post|put/i)) { sections = sectionConfig.getAffectedSections(settings.url); if (sections) { customerData.invalidate(sections); redirects = ['redirect', 'backUrl']; if (_.isObject(xhr.responseJSON) && !_.isEmpty(_.pick(xhr.responseJSON, redirects))) { return; } customerData.reload(sections, true); } } });
When any request gets complete on DOM it’s looks for the section, if section is there it reload
the section.
Let’s create Webkul/Knockout/etc/frontend/sections.xml file
here you can see we have defined our Controller path.
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd"> <action name="knockout/ajax/cartUpdate"> <section name="cart"/> </action> </config>
2. Now Create js file where you need to update the Minicart.
Note: You can read our another blog: How to use Knockout JS on custom template in Magento2 for help with knockout in magento.
define([ 'jquery', 'uiComponent', 'mage/validation', 'ko', 'mage/storage', 'mage/url', 'mage/cookies' ], function ($, Component, validation, ko, storage, urlBuilder) { 'use strict'; return Component.extend({ defaults: { template: 'Webkul_Knockout/knockout-test' }, initialize: function () { this._super(); var self = this; //Here, we have used click event on custom button with class '.update-minicart'. $("body").on("click", ".update-minicart", function () { self.updateMinicart(); }) }, //call this function on button click updateMinicart: function () { this._ajax('knockout/ajax/cartUpdate', { item_id: 436, //change item id according to test item_qty: 3 //qty you want to update }); }, /** * @param {String} url - ajax url * @param {Object} data - post data for ajax call * @param {Object} elem - element that initiated the event * @param {Function} callback - callback method to execute after AJAX success */ _ajax: function (url, data) { $.extend(data, { 'form_key': $.mage.cookies.get('form_key') }); $.ajax({ url: urlBuilder.build(url), data: data, type: 'post', dataType: 'json', context: this, }).done(function (response) { alert('hey! you updated successfully, checkout mini cart.') }) .fail(function (error) { console.log(JSON.stringify(error)); }); }, }); } );
For test, you can use the following html file.
File: Webkul/Knockout/view/frontend/web/template/knockout-test.html
<div class="customcomponent-wrapper" data-block="customcomponent"> <button type="button" class="update-minicart"><span data-bind="i18n: 'Update Minicart'"></span></button> </div>
3. Finally the last thing is to create Controller File:
Webkul/Knockout/Controller/Ajax/CartUpdate.php
<?php namespace Webkul\Knockout\Controller\Ajax; use Magento\Checkout\Model\Sidebar; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\App\Response\Http; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Json\Helper\Data; use Psr\Log\LoggerInterface; use Magento\Checkout\Model\Cart; class CartUpdate extends Action { /** * @var Sidebar */ protected $sidebar; /** * @var LoggerInterface */ protected $logger; /** * @var Data */ protected $jsonHelper; /** * @var Cart */ protected $cart; /** * @param Context $context * @param Cart $cart * @param \Magento\Checkout\Model\Session $checkoutSession * @param Sidebar $sidebar * @param LoggerInterface $logger * @param Data $jsonHelper */ public function __construct( Context $context, Cart $cart, \Magento\Checkout\Model\Session $checkoutSession, Sidebar $sidebar, LoggerInterface $logger, Data $jsonHelper ) { $this->sidebar = $sidebar; $this->logger = $logger; $this->jsonHelper = $jsonHelper; $this->_checkoutSession = $checkoutSession; $this->cart = $cart; parent::__construct($context); } /** * @return $this */ public function execute() { $itemId = (int)$this->getRequest()->getParam('item_id'); $itemQty = (int)$this->getRequest()->getParam('item_qty'); try { $this->updateQuoteItem($itemId, $itemQty); return $this->jsonResponse(); } catch (LocalizedException $e) { return $this->jsonResponse($e->getMessage()); } catch (\Exception $e) { $this->logger->critical($e); return $this->jsonResponse($e->getMessage()); } } /** * Update quote item * * @param int $itemId * @param int $itemQty * @throws LocalizedException * @return $this */ public function updateQuoteItem($itemId, $itemQty) { $itemData = [$itemId => ['qty' => $itemQty]]; $this->cart->updateItems($itemData)->save(); } /** * Get quote object associated with cart. By default it is current customer session quote * * @return \Magento\Quote\Model\Quote */ public function getQuote() { return $this->_checkoutSession->getQuote(); } /** * Compile JSON response * * @param string $error * @return Http */ protected function jsonResponse($error = '') { return $this->getResponse()->representJson( $this->jsonHelper->jsonEncode($this->sidebar->getResponseData($error)) ); } }
That’s it.
4 comments