9

How can you add an "Empty Cart" button to the minicart in Magento 2.

enter image description here

Is it possible with layout xml?

14

I have just created a proper module for your question:

We need to declare the custom js component and html template:

app/code/Vendor/MiniCart/view/frontend/layout/default.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="minicart">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="types" xsi:type="array"/>
                    <item name="components" xsi:type="array">
                        <item name="minicart_content" xsi:type="array">
                            <item name="component" xsi:type="string">Vendor_MiniCart/js/view/minicart</item>
                            <item name="config" xsi:type="array">
                                <item name="template" xsi:type="string">Vendor_MiniCart/minicart/content</item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

app/code/Vendor/MiniCart/view/frontend/web/js/view/minicart.js

   define([
    'jquery',
    'Magento_Checkout/js/view/minicart',
    'Magento_Ui/js/modal/alert',
    'Magento_Ui/js/modal/confirm'
], function ($ ,Component, alert, confirm) {
    'use strict';

    return Component.extend({
        confirmMessage: $.mage.__('Are you sure you would like to remove all items from the shopping cart?'),
        emptyCartUrl: window.checkout.emptyMiniCart,

        emptyCartAction: function (element) {
            var self = this,
                href = self.emptyCartUrl;
            $(element).on('click', function () {
                var el = this;
                confirm({
                    content: self.confirmMessage,
                    actions: {
                        confirm: function () {
                            self._removeAllItems(href, el);
                        },
                        always: function (event) {
                            event.stopImmediatePropagation();
                        }
                    }
                });
            });
        },

        _removeAllItems: function (href, elem) {
            $.ajax({
                url: href,
                type: 'post',
                dataType: 'json',
                beforeSend: function () {
                    $(elem).attr('disabled', 'disabled');
                },
                complete: function () {
                    $(elem).attr('disabled', null);
                }

            }).done(function (response) {
                if (!response.errors) {

                } else {
                    var msg = response.message;

                    if (msg) {
                        alert({
                            content: msg
                        });
                    }
                }
            }).fail(function (error) {
                console.log(JSON.stringify(error));
            });
        }
    });
});

emptyCartUrl: window.checkout.emptyMiniCart, we will get the empty link from checkout config: app/code/Vendor/MiniCart/Plugin/Cart/ConfigPlugin.php (declare later).

We need to copy the minicart content from the original file: vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html. And then, in our custom file, we need to add the action text:

app/code/Vendor/MiniCart/view/frontend/web/template/minicart/content.html

 <!-- ko if: getCartParam('summary_count') -->
    <div class="actions">
        <div class="secondary">
            <a class="action empty-cart" id="empty-minicart" data-bind="afterRender: emptyCartAction">
                <span><!-- ko i18n: 'Empty Cart Now' --><!-- /ko --></span>
            </a>
        </div>
    </div>
 <!-- /ko -->

Declare DI to add the empty link to checkout config:

app/code/Vendor/MiniCart/etc/frontend/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Cart\Sidebar">
        <plugin name="empty_cart_url" type="Vendor\MiniCart\Plugin\Cart\ConfigPlugin" sortOrder="20" />
    </type>
</config>

app/code/Vendor/MiniCart/Plugin/Cart/ConfigPlugin.php

<?php

namespace Vendor\MiniCart\Plugin\Cart;

use Magento\Framework\UrlInterface;

class ConfigPlugin
{
    /**
     * @var UrlInterface
     */
    protected $url;

    /**
     * ConfigPlugin constructor.
     * @param UrlInterface $url
     */
    public function __construct(
        UrlInterface $url
    ) {
        $this->url = $url;
    }

    /**
     * @param \Magento\Checkout\Block\Cart\Sidebar $subject
     * @param array $result
     * @return array
     */
    public function afterGetConfig(
        \Magento\Checkout\Block\Cart\Sidebar $subject,
        array $result
    ) {
        $result['emptyMiniCart'] = $this->url->getUrl('minicart/cart/emptycart');
        return $result;
    }
}

Now, we need to build the controller:

app/code/Vendor/MiniCart/etc/frontend/routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="minicart" frontName="minicart">
            <module name="Vendor_MiniCart" />
        </route>
    </router>
</config>

app/code/Vendor/MiniCart/Controller/Cart/EmptyCart.php

<?php

namespace Vendor\MiniCart\Controller\Cart;

use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Json\Helper\Data;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Checkout\Model\Session;
use Psr\Log\LoggerInterface;

class EmptyCart extends Action
{
    /**
     * @var Session
     */
    protected $checkoutSession;

    /**
     * @var JsonFactory
     */
    protected $jsonFactory;

    /**
     * @var Data
     */
    protected $jsonHelper;

    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @var Magento\Checkout\Model\Cart
     */
    protected $cart;

    /**
     * EmptyCart constructor.
     *
     * @param Context $context
     * @param Session $session
     * @param JsonFactory $jsonFactory
     * @param Data $jsonHelper
     * @param LoggerInterface $logger
     */
    public function __construct(
        Context $context,
        Session $session,
        JsonFactory $jsonFactory,
        Data $jsonHelper,
        LoggerInterface $logger,
        \Magento\Checkout\Model\Cart $cart
    ) {
        $this->checkoutSession = $session;
        $this->jsonFactory = $jsonFactory;
        $this->jsonHelper = $jsonHelper;
        $this->logger = $logger;
        $this->cart = $cart;
        parent::__construct($context);
    }

    /**
     * Ajax execute
     *
     */
    public function execute()
    {
        $response = [
            'errors' => false
        ];

        if ($this->getRequest()->isAjax()) {
            try {
                $this->cart->truncate()->save();
                $response['message'] = __('Empty Cart.');

            } catch (\Exception $e) {
                $response = [
                    'errors' => true,
                    'message' => __('Some thing went wrong.')
                ];
                $this->logger->critical($e);
            }
        } else {
            $response = [
                'errors' => true,
                'message' => __('Need to access via Ajax.')
            ];
        }
        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
        $resultJson = $this->jsonFactory->create();
        return $resultJson->setData($response);
    }
}

Need to reload cart section:

app/code/Vendor/MiniCart/etc/frontend/sections.xml

<?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="minicart/cart/empty">
        <section name="cart"/>
    </action>
</config>

Remember to create registration.php and module.xml

app/code/Vendor/MiniCart/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_MiniCart',
    __DIR__
);

app/code/Vendor/MiniCart/etc/module.xml

<?xml version="1.0"?>

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

[IMAGES DEMO]

Mini Cart:

enter image description here

Message Confirmation:

enter image description here

  • Thanks for such detailed and complete solution! It worked, except code to empty cart. To make it work on 2.1.10 I've had to change it a bit pastebin.com/sYmhqYRL – Viperet Dec 14 '17 at 10:45
  • 2
    And even a bit shorter pastebin.com/2tMEMdeA – Viperet Dec 14 '17 at 11:23
  • 1
    @Viperet I agree with you. Should use $this->cart->truncate()->save();. Feel free to edit my answer. – Khoa TruongDinh Dec 14 '17 at 11:54
  • @KhoaTruongDinh mini cart showing only "Empty Cart Now" button after implementing above code. Any solution? – Vishal Jan 12 '18 at 13:51
  • 1
    My Magento version is 2.2.6. Can you please help me? – Rohan Hapani Jan 23 at 7:23
0

Something like this also can be worked out.

In your phtml file, button tag like this

<?php $_helper = $this->helper('Namespace\Modulename\Helper\Data'); ?>

<button id="clear-cart" class="action tocart primary" title="<?php echo __('Clear Cart') ?>" ><?php echo __('Clear Cart') ?></button>

and javascript function for onclick, like this

<script type="text/javascript">
        document.getElementById("clear-cart").onclick = function () {
            location.href = '<?php echo $_helper->getClearCartUrl(); ?>';
        };
    </script>

As I have called helper function on click location, we need to create helper function in any of our helper class. Like this,

public function getClearCartUrl(){
        $checkoutSession = $this->getCheckoutSession();
        $quoteId = $checkoutSession->getQuote()->getId();
        $quoteItem = $this->getQuoteModel()->load($quoteId);
        $quoteItem->delete();
        return $this->storeManager->getStore()->getBaseUrl() .'checkout/cart/' ;  //Need to load $this->storeManager in construct method to get Base URL
    }

    public function getCheckoutSession(){
        $checkoutSession = $this->_objectManager->get('Magento\Checkout\Model\Session');//checkout session
        return $checkoutSession;
    }

    public function getQuoteModel(){
        $quoteModel = $this->_objectManager->create('Magento\Quote\Model\Quote');//Quote item model to load quote
        return $quoteModel;
    }

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.