4

I have a relatively stock minicart implementation, and I wanted to know if there is a configuration option or some other way of setting up the mini cart to drop down (open) when an item is successfully added to your cart on the frontend

Current behavior is the item count updates, but the minicart dropdown stays closed. Thanks!

  • Hi @Pat Welcome to Magento SE – Ankit Shah Oct 19 '16 at 3:02
3

For Magento 2

Pop up minicart when I add a product to the cart magento 2

I'm referring to Open header cart when product added to cart & https://stackoverflow.com/questions/13841390/toggle-dropdown-mini-cart-when-product-added-to-basket which are in Magento 1.

In Magento 2 we can create Event Observer for this

app\code\Custom\Module\etc\frontend\events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_predispatch_checkout_cart_add">
        <observer name="open_mini_cart" instance="Custom\Module\Observer\OpenMiniCartObserver" />
    </event>
</config>

app\code\Custom\Module\Observer\OpenMiniCartObserver.php

namespace Custom\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class OpenMiniCartObserver implements ObserverInterface {

    protected $_urlManager;
    protected $redirect;

    public function __construct(
\Magento\Framework\UrlInterface $urlManager, \Magento\Framework\App\Response\RedirectInterface $redirect
) {
        $this->_urlManager = $urlManager;
        $this->redirect = $redirect;
    }

 public function execute(\Magento\Framework\Event\Observer $observer) {

    $actionName = $observer->getEvent()->getRequest()->getFullActionName();
    $controller = $observer->getControllerAction();
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

    $cartUpdated = $objectManager->get('Magento\Checkout\Model\Session')->getCartWasUpdated(false);

    if ($cartUpdated) {
        // open mini cart
    }
    $this->redirect->redirect($controller->getResponse(), $this->redirect->getRefererUrl());
}

Still Some JS Stuff missing

  • So I'm not sure the event aspects are really necessary, but the first link you provided had the js component that did the trick, thanks! – Pat Marx Oct 19 '16 at 18:50
  • Wow Great @PatMarx Good to Hear that :) – Ankit Shah Oct 20 '16 at 1:19
9

It can be done by simply modifying minicart.js file.

Navigate to vendor/magento/Magento_Checkout/view/web/js/view/minicart.js

Create override of the file by copy it in your theme folder.

Under initialize: function, you will see

$('[data-block="minicart"]').on('contentLoading', function (event) {

Replace the function with this code.

$('[data-block="minicart"]').on('contentLoading', function (event) {
            addToCartCalls++;
            self.isLoading(true);
            $('[data-block="minicart"]').on('contentUpdated', function ()  {
                $('[data-block="minicart"]').find('[data-role="dropdownDialog"]').dropdownDialog("open");

                setTimeout(function() {
                    $('[data-block="minicart"]').find('[data-role="dropdownDialog"]').dropdownDialog("close");
                }, 4000);
            });
        });

You can change the timeout as per your requirement.

upload the file and clean cache by running the command

php bin/magento cache:clean

Cheers!

  • I wouldn't recommend editing the vendor files... make the update in your theme – Sam Holguin Jan 27 '18 at 12:27
  • Yes i missed to mention the override of file, updated the answer :) – Ajendra Panwar Feb 1 '18 at 13:40
  • i tested but it's not working. – Anas Mansuri Jun 6 at 8:41
  • This won't work with login customers add wishlist items to their cart. I have posted answer which worked for me on every pages. – Dinesh Rajput Jul 8 at 11:33
3

Ajendra Panwar's answer is good but i wanted to point out that you can do this exact same thing without having to override the whole mini cart JS file. Doing this override can lead to upgrade problems, and since you just have to hook into the same functionality that it's using, the override is unnecessary. I made the call to Js file in my override of the header.phtml but this can go in any phtml file that is loaded on every page of the site:

app/design/frontend/{namespace}/{theme}/Magento_Theme/templates/html/header.phtml

...
<script type="text/x-magento-init">
{
    "*": {
        "Magento_Theme/js/mini-cart-action": {}
    }
}
</script>
...

And then create a JS file for our code:

app/design/frontend/{namespace}/{theme}/Magento_Theme/web/js/mini-cart-action.js

define([
    'jquery'
], function ($) {
    return function () {
        $('[data-block="minicart"]').on('contentLoading', function () {
            $('[data-block="minicart"]').on('contentUpdated', function ()  {
                $('html, body').animate({ scrollTop: 0 }, 'slow');
                $('[data-block="minicart"]').find('[data-role="dropdownDialog"]').dropdownDialog("open");
            });
        });
    }
});

Be sure to clear your cache and redeploy so your JS file is in the pub folder. To make sure the file is loading correctly, you can look in the network tap of any page on the site:

enter image description here

1

Please add it to your file where its being called on every page: Note:This will also work with AJAX add to cart.

<script type="text/javascript">
require(['jquery', 'jquery/ui'], function($){
    jQuery(document).ready(minicartOpenClose);
    function minicartOpenClose () {
        if($('.message-success').is(':visible') && ($('.counter-number').text() > 0)){
            var successMsg = $('.message-success').text();
            var msgOne = "been added to shopping cart";
            var msgTwo = "to your shopping cart";
            if(successMsg.includes(msgOne) || successMsg.includes(msgTwo)){
                $('.action.showcart').trigger("click");
                setTimeout(function(){
                    if($('.action.showcart').hasClass('active')){
                        $('.action.showcart').trigger("click");
                    }
                }, 7000); 
            }
        } else {
            setTimeout(minicartOpenClose, 50);
        }
    }
});

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.