2

I have normal magento 2.3.3 which has the default mini cart as shown below.

The basic mini cart

And in the above pic by default the quantity as to be manually entered and updated the cart on click.

But I want a mini cart that should have a plus and minus symbol, with synchronous cart update i.e without clicking update cart.

The example has been shown below.

Nedd to bring a mini cart like this

Thanks for the answers in advance.

4
  • Did you got solution for this? Commented Dec 24, 2019 at 4:21
  • No ,I didn't get the answer yet. @Ranganathan
    – Haerriz
    Commented Dec 24, 2019 at 4:23
  • 1
    ok, I will post my answer. Commented Dec 24, 2019 at 4:23
  • 1
    You can use this extension github.com/php-cuong/magento2-qty and modify to hide the Update button and trigger the update button on qty increase or decrease. Commented Dec 24, 2019 at 4:32

2 Answers 2

7

Override default.html from

vendor\magento\module-checkout\view\frontend\web\template\minicart\item\default.html

to

app\design\yourvendor\yourtheme\Magento_Checkout\web\template\minicart\item\default.html

add + and - button as span tag in line number 74 and 84.

<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<li class="item product product-item" data-role="product-item">
    <div class="product">
        <!-- ko if: product_has_url -->
        <a data-bind="attr: {href: product_url, title: product_name}" tabindex="-1" class="product-item-photo">
            <!-- ko foreach: $parent.getRegion('itemImage') -->
                <!-- ko template: {name: getTemplate(), data: item.product_image} --><!-- /ko -->
            <!-- /ko -->
        </a>
        <!-- /ko -->
        <!-- ko ifnot: product_has_url -->
        <span class="product-item-photo">
            <!-- ko foreach: $parent.getRegion('itemImage') -->
                <!-- ko template: {name: getTemplate(), data: item.product_image} --><!-- /ko -->
            <!-- /ko -->
        </span>
        <!-- /ko -->

        <div class="product-item-details">
            <strong class="product-item-name">
                <!-- ko if: product_has_url -->
                <a data-bind="attr: {href: product_url}, html: product_name"></a>
                <!-- /ko -->
                <!-- ko ifnot: product_has_url -->
                    <!-- ko text: product_name --><!-- /ko -->
                <!-- /ko -->
            </strong>

            <!-- ko if: options.length -->
            <div class="product options" data-mage-init='{"collapsible":{"openedState": "active", "saveState": false}}'>
                <span data-role="title" class="toggle"><!-- ko i18n: 'See Details' --><!-- /ko --></span>

                <div data-role="content" class="content">
                    <strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko --></strong>
                    <dl class="product options list">
                        <!-- ko foreach: { data: options, as: 'option' } -->
                        <dt class="label"><!-- ko text: option.label --><!-- /ko --></dt>
                        <dd class="values">
                            <!-- ko if: Array.isArray(option.value) -->
                                <span data-bind="html: option.value.join('<br>')"></span>
                            <!-- /ko -->
                            <!-- ko ifnot: Array.isArray(option.value) -->
                                <span data-bind="text: option.value"></span>
                            <!-- /ko -->
                        </dd>
                        <!-- /ko -->
                    </dl>
                </div>
            </div>
            <!-- /ko -->

            <div class="product-item-pricing">
                <!-- ko if: canApplyMsrp -->

                <div class="details-map">
                    <span class="label" data-bind="i18n: 'Price'"></span>
                    <span class="value" data-bind="i18n: 'See price before order confirmation.'"></span>
                </div>
                <!-- /ko -->
                <!-- ko ifnot: canApplyMsrp -->
                <!-- ko foreach: $parent.getRegion('priceSidebar') -->
                    <!-- ko template: {name: getTemplate(), data: item.product_price, as: 'price'} --><!-- /ko -->
                <!-- /ko -->
                <!-- /ko -->

                <div class="details-qty qty">
                    <label class="label" data-bind="i18n: 'Qty', attr: {
                           for: 'cart-item-'+item_id+'-qty'}"></label>
                    <span class="minus">-</span>
                    <input data-bind="attr: {
                           id: 'cart-item-'+item_id+'-qty',
                           'data-cart-item': item_id,
                           'data-item-qty': qty,
                           'data-cart-item-id': product_sku
                           }, value: qty"
                           type="number"
                           size="4"
                           class="item-qty cart-item-qty">
                    <span class="plus">+</span>
                    <button data-bind="attr: {
                           id: 'update-cart-item-'+item_id,
                           'data-cart-item': item_id,
                           title: $t('Update')
                           }"
                            class="update-cart-item"
                            style="display: none">
                        <span data-bind="i18n: 'Update'"></span>
                    </button>
                </div>
            </div>

            <div class="product actions">
                <!-- ko if: is_visible_in_site_visibility -->
                <div class="primary">
                    <a data-bind="attr: {href: configure_url, title: $t('Edit item')}" class="action edit">
                        <span data-bind="i18n: 'Edit'"></span>
                    </a>
                </div>
                <!-- /ko -->
                <div class="secondary">
                    <a href="#" data-bind="attr: {'data-cart-item': item_id, title: $t('Remove item')}"
                       class="action delete">
                        <span data-bind="i18n: 'Remove'"></span>
                    </a>
                </div>
            </div>
        </div>
    </div>
</li>

override sidebar.js from

vendor\magento\module-checkout\view\frontend\web\js\sidebar.js

to

app\design\yourvendor\yourtheme\Magento_Checkout\web\js\sidebar.js

marked my custom codes in comments. Please take a look

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

define([
    'jquery',
    'Magento_Customer/js/model/authentication-popup',
    'Magento_Customer/js/customer-data',
    'Magento_Ui/js/modal/alert',
    'Magento_Ui/js/modal/confirm',
    'underscore',
    'jquery/ui',
    'mage/decorate',
    'mage/collapsible',
    'mage/cookies'
], function ($, authenticationPopup, customerData, alert, confirm, _) {
    'use strict';

    $.widget('mage.sidebar', {
        options: {
            isRecursive: true,
            minicart: {
                maxItemsVisible: 3
            }
        },
        scrollHeight: 0,
        shoppingCartUrl: window.checkout.shoppingCartUrl,

        /**
         * Create sidebar.
         * @private
         */
        _create: function () {
            this._initContent();
        },

        /**
         * Update sidebar block.
         */
        update: function () {
            $(this.options.targetElement).trigger('contentUpdated');
            this._calcHeight();
            this._isOverflowed();
        },

        /**
         * @private
         */
        _initContent: function () {
            var self = this,
                events = {};

            this.element.decorate('list', this.options.isRecursive);

            /**
             * @param {jQuery.Event} event
             */
            events['click ' + this.options.button.close] = function (event) {
                event.stopPropagation();
                $(self.options.targetElement).dropdownDialog('close');
            };
            events['click ' + this.options.button.checkout] = $.proxy(function () {
                var cart = customerData.get('cart'),
                    customer = customerData.get('customer'),
                    element = $(this.options.button.checkout);

                if (!customer().firstname && cart().isGuestCheckoutAllowed === false) {
                    // set URL for redirect on successful login/registration. It's postprocessed on backend.
                    $.cookie('login_redirect', this.options.url.checkout);

                    if (this.options.url.isRedirectRequired) {
                        element.prop('disabled', true);
                        location.href = this.options.url.loginUrl;
                    } else {
                        authenticationPopup.showModal();
                    }

                    return false;
                }
                element.prop('disabled', true);
                location.href = this.options.url.checkout;
            }, this);

            /**
             * @param {jQuery.Event} event
             */
            events['click ' + this.options.button.remove] =  function (event) {
                event.stopPropagation();
                confirm({
                    content: self.options.confirmMessage,
                    actions: {
                        /** @inheritdoc */
                        confirm: function () {
                            self._removeItem($(event.currentTarget));
                        },

                        /** @inheritdoc */
                        always: function (e) {
                            e.stopImmediatePropagation();
                        }
                    }
                });
            };

            /**
             * @param {jQuery.Event} event
             */
            events['click ' + '.minicart-items-wrapper .plus'] = function (event) {//Custom event
                var qtyVal = parseInt($(event.target).parent().find(this.options.item.qty).val());
                $(this.options.item.qty).val(qtyVal + 1);
                event.stopPropagation();
                self._updateItemQty($(event.target).parent().find(this.options.item.button));
            };

            /**
             * @param {jQuery.Event} event
             */
            events['click ' + '.minicart-items-wrapper .minus'] = function (event) {//Custom event
                var qtyVal = parseInt($(event.target).parent().find(this.options.item.qty).val());
                if(qtyVal > 1){
                    $(this.options.item.qty).val(qtyVal - 1);
                    event.stopPropagation();
                    self._updateItemQty($(event.target).parent().find(this.options.item.button));
                }
            };

            /**
             * @param {jQuery.Event} event
             */
            events['keyup ' + this.options.item.qty] = function (event) {//Hide event for not displaying update button
                //self._showItemButton($(event.target));
            };

            /**
             * @param {jQuery.Event} event
             */
            events['change ' + this.options.item.qty] = function (event) {//Hide event for not displaying update button
                //self._showItemButton($(event.target));
            };

            /**
             * @param {jQuery.Event} event
             */
            events['click ' + this.options.item.button] = function (event) {
                event.stopPropagation();
                self._updateItemQty($(event.currentTarget));
            };

            /**
             * @param {jQuery.Event} event
             */
            events['focusout ' + this.options.item.qty] = function (event) {
                self._validateQty($(event.currentTarget));
            };

            this._on(this.element, events);
            this._calcHeight();
            this._isOverflowed();
        },

        /**
         * Add 'overflowed' class to minicart items wrapper element
         *
         * @private
         */
        _isOverflowed: function () {
            var list = $(this.options.minicart.list),
                cssOverflowClass = 'overflowed';

            if (this.scrollHeight > list.innerHeight()) {
                list.parent().addClass(cssOverflowClass);
            } else {
                list.parent().removeClass(cssOverflowClass);
            }
        },

        /**
         * @param {HTMLElement} elem
         * @private
         */
        _showItemButton: function (elem) {
            var itemId = elem.data('cart-item'),
                itemQty = elem.data('item-qty');

            if (this._isValidQty(itemQty, elem.val())) {
                $('#update-cart-item-' + itemId).show('fade', 300);
            } else if (elem.val() == 0) { //eslint-disable-line eqeqeq
                this._hideItemButton(elem);
            } else {
                this._hideItemButton(elem);
            }
        },

        /**
         * @param {*} origin - origin qty. 'data-item-qty' attribute.
         * @param {*} changed - new qty.
         * @returns {Boolean}
         * @private
         */
        _isValidQty: function (origin, changed) {
            return origin != changed && //eslint-disable-line eqeqeq
                changed.length > 0 &&
                changed - 0 == changed && //eslint-disable-line eqeqeq
                changed - 0 > 0;
        },

        /**
         * @param {Object} elem
         * @private
         */
        _validateQty: function (elem) {
            var itemQty = elem.data('item-qty');

            if (!this._isValidQty(itemQty, elem.val())) {
                elem.val(itemQty);
            }
        },

        /**
         * @param {HTMLElement} elem
         * @private
         */
        _hideItemButton: function (elem) {
            var itemId = elem.data('cart-item');

            $('#update-cart-item-' + itemId).hide('fade', 300);
        },

        /**
         * @param {HTMLElement} elem
         * @private
         */
        _updateItemQty: function (elem) {
            var itemId = elem.data('cart-item');

            this._ajax(this.options.url.update, {
                'item_id': itemId,
                'item_qty': $('#cart-item-' + itemId + '-qty').val()
            }, elem, this._updateItemQtyAfter);
        },

        /**
         * Update content after update qty
         *
         * @param {HTMLElement} elem
         */
        _updateItemQtyAfter: function (elem) {
            var productData = this._getProductById(Number(elem.data('cart-item')));

            if (!_.isUndefined(productData)) {
                $(document).trigger('ajax:updateCartItemQty');

                if (window.location.href === this.shoppingCartUrl) {
                    window.location.reload(false);
                }
            }
            this._hideItemButton(elem);
        },

        /**
         * @param {HTMLElement} elem
         * @private
         */
        _removeItem: function (elem) {
            var itemId = elem.data('cart-item');

            this._ajax(this.options.url.remove, {
                'item_id': itemId
            }, elem, this._removeItemAfter);
        },

        /**
         * Update content after item remove
         *
         * @param {Object} elem
         * @private
         */
        _removeItemAfter: function (elem) {
            var productData = this._getProductById(Number(elem.data('cart-item')));

            if (!_.isUndefined(productData)) {
                $(document).trigger('ajax:removeFromCart', {
                    productIds: [productData['product_id']]
                });
            }
        },

        /**
         * Retrieves product data by Id.
         *
         * @param {Number} productId - product Id
         * @returns {Object|undefined}
         * @private
         */
        _getProductById: function (productId) {
            return _.find(customerData.get('cart')().items, function (item) {
                return productId === Number(item['item_id']);
            });
        },

        /**
         * @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, elem, callback) {
            $.extend(data, {
                'form_key': $.mage.cookies.get('form_key')
            });

            $.ajax({
                url: url,
                data: data,
                type: 'post',
                dataType: 'json',
                context: this,

                /** @inheritdoc */
                beforeSend: function () {
                    elem.attr('disabled', 'disabled');
                },

                /** @inheritdoc */
                complete: function () {
                    elem.attr('disabled', null);
                }
            })
                .done(function (response) {
                    var msg;

                    if (response.success) {
                        callback.call(this, elem, response);
                    } else {
                        msg = response['error_message'];

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

        /**
         * Calculate height of minicart list
         *
         * @private
         */
        _calcHeight: function () {
            var self = this,
                height = 0,
                counter = this.options.minicart.maxItemsVisible,
                target = $(this.options.minicart.list),
                outerHeight;

            self.scrollHeight = 0;
            target.children().each(function () {

                if ($(this).find('.options').length > 0) {
                    $(this).collapsible();
                }
                outerHeight = $(this).outerHeight();

                if (counter-- > 0) {
                    height += outerHeight;
                }
                self.scrollHeight += outerHeight;
            });

            target.parent().height(height);
        }
    });

    return $.mage.sidebar;
});
2
  • Thanks for the answer it's working good. Commented Dec 7, 2020 at 9:40
  • Is it your soltion work for 2.4.1?
    – zus
    Commented Apr 12, 2021 at 11:34
0

Override default.html from

and paste this code

    <div class="product-item-details">
        <strong class="product-item-name">
            <!-- ko if: product_has_url -->
            <a data-bind="attr: {href: product_url}, html: $parent.getProductNameUnsanitizedHtml(product_name)"></a>
            <!-- /ko -->
            <!-- ko ifnot: product_has_url -->
                <span data-bind="html: $parent.getProductNameUnsanitizedHtml(product_name)"></span>
            <!-- /ko -->
        </strong>

        <!-- ko if: options.length -->
        <div class="product options" data-mage-init='{"collapsible":{"openedState": "active", "saveState": false}}'>
            <span data-role="title" class="toggle"><!-- ko i18n: 'See Details' --><!-- /ko --></span>

            <div data-role="content" class="content">
                <strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko --></strong>
                <dl class="product options list">
                    <!-- ko foreach: { data: options, as: 'option' } -->
                    <dt class="label"><!-- ko text: option.label --><!-- /ko --></dt>
                    <dd class="values">
                        <!-- ko if: Array.isArray(option.value) -->
                            <span data-bind="html: $parents[1].getOptionValueUnsanitizedHtml(option.value.join('<br/>'))"></span>
                        <!-- /ko -->
                        <!-- ko if: (!Array.isArray(option.value) && ['file', 'html'].includes(option.option_type)) -->
                            <span data-bind="html: $parents[1].getOptionValueUnsanitizedHtml(option.value)"></span>
                        <!-- /ko -->
                        <!-- ko if: (!Array.isArray(option.value) && !['file', 'html'].includes(option.option_type)) -->
                        <span data-bind="text: option.value"></span>
                        <!-- /ko -->
                    </dd>
                    <!-- /ko -->
                </dl>
            </div>
        </div>
        <!-- /ko -->

        <div class="product-item-pricing">
            <!-- ko if: canApplyMsrp -->

            <div class="details-map">
                <span class="label" data-bind="i18n: 'Price'"></span>
                <span class="value" data-bind="i18n: 'See price before order confirmation.'"></span>
            </div>
            <!-- /ko -->
            <!-- ko ifnot: canApplyMsrp -->
            <!-- ko foreach: $parent.getRegion('priceSidebar') -->
                <!-- ko template: {name: getTemplate(), data: item.product_price, as: 'price'} --><!-- /ko -->
            <!-- /ko -->
            <!-- /ko -->

            <div class="details-qty qty">
                 <label class="label" data-bind="i18n: 'Qty', attr: {
                       for: 'cart-item-'+item_id+'-qty'}"></label> 
               <span data-bind="attr: {
                       id: item_id
                       }" class="minus" >-</span>
                <input data-bind="attr: {
                       id: 'cart-item-'+item_id+'-qty',
                       'data-cart-item': item_id,
                       'data-item-qty': qty,
                       'data-cart-item-id': product_sku
                       }, value: qty"
                       type="number"
                       size="4"
                       readonly="" 
                       class="item-qty cart-item-qty qty">
                <span data-bind="attr: {
                       id: item_id
                       }" class="plus">+</span>
                <button data-bind="attr: {
                       id: 'update-cart-item-'+item_id,
                       'data-cart-item': item_id,
                       title: $t('Update')
                       }"
                        class="update-cart-item"
                        style="display: none">
                   <!--  <span data-bind="i18n: 'Update'"></span> -->
                </button>
            </div>
        </div>

=========================

override sidebar.js from and paste this code

define([ 'jquery', 'Magento_Customer/js/model/authentication-popup', 'Magento_Customer/js/customer-data', 'Magento_Ui/js/modal/alert', 'Magento_Ui/js/modal/confirm', 'underscore', 'jquery/ui', 'mage/decorate', 'mage/collapsible', 'mage/cookies' ], function ($, authenticationPopup, customerData, alert, confirm, _) { 'use strict';

$.widget('mage.sidebar', {
    options: {
        isRecursive: true,
        minicart: {
            maxItemsVisible: 3
        }
    },
    scrollHeight: 0,
    shoppingCartUrl: window.checkout.shoppingCartUrl,

    /**
     * Create sidebar.
     * @private
     */
    _create: function () {
        this._initContent();
    },

    /**
     * Update sidebar block.
     */
    update: function () {
        $(this.options.targetElement).trigger('contentUpdated');
        this._calcHeight();
        this._isOverflowed();
    },

    /**
     * @private
     */
    _initContent: function () {
        var self = this,
            events = {};

        this.element.decorate('list', this.options.isRecursive);

        /**
         * @param {jQuery.Event} event
         */
        events['click ' + this.options.button.close] = function (event) {
            event.stopPropagation();
            $(self.options.targetElement).dropdownDialog('close');
        };
        events['click ' + this.options.button.checkout] = $.proxy(function () {
            var cart = customerData.get('cart'),
                customer = customerData.get('customer'),
                element = $(this.options.button.checkout);

            if (!customer().firstname && cart().isGuestCheckoutAllowed === false) {
                // set URL for redirect on successful login/registration. It's postprocessed on backend.
                $.cookie('login_redirect', this.options.url.checkout);

                if (this.options.url.isRedirectRequired) {
                    element.prop('disabled', true);
                    location.href = this.options.url.loginUrl;
                } else {
                    authenticationPopup.showModal();
                }

                return false;
            }
            element.prop('disabled', true);
            location.href = this.options.url.checkout;
        }, this);

        /**
         * @param {jQuery.Event} event
         */
        events['click ' + this.options.button.remove] =  function (event) {
            event.stopPropagation();
            confirm({
                content: self.options.confirmMessage,
                actions: {
                    /** @inheritdoc */
                    confirm: function () {
                        self._removeItem($(event.currentTarget));
                    },

                    /** @inheritdoc */
                    always: function (e) {
                        e.stopImmediatePropagation();
                    }
                }
            });
        };

        /**
         * @param {jQuery.Event} event
         */
        events['click ' + '.minicart-items-wrapper .plus'] = function (event) {//Custom event
            var plusId=event.target.id;
            var qtyBoxId='#cart-item-'+plusId+'-qty';
            var qtyVal = parseInt($(event.target).parent().find(this.options.item.qty).val());
            $(qtyBoxId).val(qtyVal + 1);
            event.stopPropagation();
            self._updateItemQty($(event.target).parent().find(this.options.item.button));
        };

        /**
         * @param {jQuery.Event} event
         */
        events['click ' + '.minicart-items-wrapper .minus'] = function (event) {//Custom event
            var minusId=event.target.id;
            var qtyBoxId='#cart-item-'+minusId+'-qty';
            var qtyVal = parseInt($(event.target).parent().find(this.options.item.qty).val());
            if(qtyVal > 1){
                $(qtyBoxId).val(qtyVal - 1);
                event.stopPropagation();
                self._updateItemQty($(event.target).parent().find(this.options.item.button));
            }
        };

        /**
         * @param {jQuery.Event} event
         */
        events['keyup ' + this.options.item.qty] = function (event) {//Hide event for not displaying update button
            //self._showItemButton($(event.target));
        };

        /**
         * @param {jQuery.Event} event
         */
        events['change ' + this.options.item.qty] = function (event) {//Hide event for not displaying update button
            //self._showItemButton($(event.target));
        };

        /**
         * @param {jQuery.Event} event
         */
        events['click ' + this.options.item.button] = function (event) {
            event.stopPropagation();
            self._updateItemQty($(event.currentTarget));
        };

        /**
         * @param {jQuery.Event} event
         */
        events['focusout ' + this.options.item.qty] = function (event) {
            self._validateQty($(event.currentTarget));
        };

        this._on(this.element, events);
        this._calcHeight();
        this._isOverflowed();
    },

    /**
     * Add 'overflowed' class to minicart items wrapper element
     *
     * @private
     */
    _isOverflowed: function () {
        var list = $(this.options.minicart.list),
            cssOverflowClass = 'overflowed';

        if (this.scrollHeight > list.innerHeight()) {
            list.parent().addClass(cssOverflowClass);
        } else {
            list.parent().removeClass(cssOverflowClass);
        }
    },

    /**
     * @param {HTMLElement} elem
     * @private
     */
    _showItemButton: function (elem) {
        var itemId = elem.data('cart-item'),
            itemQty = elem.data('item-qty');

        if (this._isValidQty(itemQty, elem.val())) {
            $('#update-cart-item-' + itemId).show('fade', 300);
        } else if (elem.val() == 0) { //eslint-disable-line eqeqeq
            this._hideItemButton(elem);
        } else {
            this._hideItemButton(elem);
        }
    },

    /**
     * @param {*} origin - origin qty. 'data-item-qty' attribute.
     * @param {*} changed - new qty.
     * @returns {Boolean}
     * @private
     */
    _isValidQty: function (origin, changed) {
        return origin != changed && //eslint-disable-line eqeqeq
            changed.length > 0 &&
            changed - 0 == changed && //eslint-disable-line eqeqeq
            changed - 0 > 0;
    },

    /**
     * @param {Object} elem
     * @private
     */
    _validateQty: function (elem) {
        var itemQty = elem.data('item-qty');

        if (!this._isValidQty(itemQty, elem.val())) {
            elem.val(itemQty);
        }
    },

    /**
     * @param {HTMLElement} elem
     * @private
     */
    _hideItemButton: function (elem) {
        var itemId = elem.data('cart-item');

        $('#update-cart-item-' + itemId).hide('fade', 300);
    },

    /**
     * @param {HTMLElement} elem
     * @private
     */
    _updateItemQty: function (elem) {
        var itemId = elem.data('cart-item');

        this._ajax(this.options.url.update, {
            'item_id': itemId,
            'item_qty': $('#cart-item-' + itemId + '-qty').val()
        }, elem, this._updateItemQtyAfter);
    },

    /**
     * Update content after update qty
     *
     * @param {HTMLElement} elem
     */
    _updateItemQtyAfter: function (elem) {
        var productData = this._getProductById(Number(elem.data('cart-item')));

        if (!_.isUndefined(productData)) {
            $(document).trigger('ajax:updateCartItemQty');

            if (window.location.href === this.shoppingCartUrl) {
                window.location.reload(false);
            }
        }
        this._hideItemButton(elem);
    },

    /**
     * @param {HTMLElement} elem
     * @private
     */
    _removeItem: function (elem) {
        var itemId = elem.data('cart-item');

        this._ajax(this.options.url.remove, {
            'item_id': itemId
        }, elem, this._removeItemAfter);
    },

    /**
     * Update content after item remove
     *
     * @param {Object} elem
     * @private
     */
    _removeItemAfter: function (elem) {
        var productData = this._getProductById(Number(elem.data('cart-item')));

        if (!_.isUndefined(productData)) {
            $(document).trigger('ajax:removeFromCart', {
                productIds: [productData['product_id']]
            });
        }
    },

    /**
     * Retrieves product data by Id.
     *
     * @param {Number} productId - product Id
     * @returns {Object|undefined}
     * @private
     */
    _getProductById: function (productId) {
        return _.find(customerData.get('cart')().items, function (item) {
            return productId === Number(item['item_id']);
        });
    },

    /**
     * @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, elem, callback) {
        $.extend(data, {
            'form_key': $.mage.cookies.get('form_key')
        });

        $.ajax({
            url: url,
            data: data,
            type: 'post',
            dataType: 'json',
            context: this,

            /** @inheritdoc */
            beforeSend: function () {
                elem.attr('disabled', 'disabled');
            },

            /** @inheritdoc */
            complete: function () {
                elem.attr('disabled', null);
            }
        })
            .done(function (response) {
                var msg;

                if (response.success) {
                    callback.call(this, elem, response);
                } else {
                    msg = response['error_message'];

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

    /**
     * Calculate height of minicart list
     *
     * @private
     */
    _calcHeight: function () {
        var self = this,
            height = 0,
            counter = this.options.minicart.maxItemsVisible,
            target = $(this.options.minicart.list),
            outerHeight;

        self.scrollHeight = 0;
        target.children().each(function () {

            if ($(this).find('.options').length > 0) {
                $(this).collapsible();
            }
            outerHeight = $(this).outerHeight();

            if (counter-- > 0) {
                height += outerHeight;
            }
            self.scrollHeight += outerHeight;
        });

        target.parent().height(height);
    }
});

return $.mage.sidebar;

});

Hope this code work perfect

1
  • @MagentoDev2 You have again suggested an edit that breaks formatting. Do not submit such edits. Commented Jul 11 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.