7

How to hide notification messages like success message after adding product to cart or any error messages or notices after few seconds after they appear on the the frontend using knockout js.

Example : When I am adding a product in the cart, a success message appear saying "product has been added to your cart". I want to hide this success message after 5 seconds after it appear on the screen.

12

Try following way:

Vendor/Module/view/frontend/requirejs-config.js

var config = {
    "map": {
        "*": {
            "Magento_Theme/js/view/messages": "Vendor_Module/js/view/messages",
        }
    }
}

Vendor/Module/view/frontend/web/js/view/messages.js

define([
    'jquery',
    'uiComponent',
    'underscore',
    'Magento_Customer/js/customer-data',
    'jquery/jquery-storageapi'
], function ($, Component, _, customerData) {
    'use strict';

    return Component.extend({
        defaults: {
            cookieMessages: [],
            messages: []
        },

        /** @inheritdoc */
        initialize: function () {
            this._super();

            this.cookieMessages = $.cookieStorage.get('mage-messages');
            this.messages = customerData.get('messages').extend({
                disposableCustomerData: 'messages'
            });

            if (!_.isEmpty(this.messages().messages)) {
                customerData.set('messages', {});
            }

            $.cookieStorage.set('mage-messages', '');
            setTimeout(function() {
                $(".messages").hide('blind', {}, 500)
            }, 5000);
        }
    });
});

Clear cache.

  • I have tried and it is not showing any message at all. – Anshu Mishra Jan 30 '17 at 5:55
  • Delete pub/static/*, clear cache. Run setup:static-content:deploy. – Sohel Rana Jan 30 '17 at 6:31
  • I have tried after cleaning the pub/static and executing the command setup:static-content:deploy , but still no effect. I have added alert in the initialize function but it is not alerting at all. I guess js file is not included properly. It would be great if you can share if anything else is required as well. – Anshu Mishra Jan 30 '17 at 7:33
  • For my case, I use SR_StackExchange is module name. And it's working fine with luma theme. – Sohel Rana Jan 30 '17 at 7:50
  • 1
    I have checked on different machine and the code seems to be working. Thanks for your answer. One more thing that I want to know is, what is the purpose of parameters 'blind' and {} in hide function. – Anshu Mishra Jan 30 '17 at 8:58
1

we can do it from js mixin

in you custom module view/frontend/requirejs-config.js

var config = {
config: {
        mixins: {
            'Magento_Ui/js/view/messages': {
                'NameSpace_Module/js/messages-mixin': true
            }
        }
    }
};

messages-mixin.js

 define([
        'jquery'
    ], function($) {
        'use strict';
        return function(targetModule) {
            return targetModule.extend({
                onHiddenChange: function (isHidden) {
                var self = this;

                // Hide message block if needed
    //            if (isHidden) {
    //                setTimeout(function () { 
    //                    $(self.selector).hide('blind', {}, 500);
    //                }, 30000);                
    //            }
                }
            });
        };

    });
1

Make a mixin as Kumar said but do not extend the Magento_Ui messages since those are for checkout etc but extend Magento_Theme messages.js. The full code is as follow.

requirejs-config.js

var config = {
    'config': {
        'mixins': {
            'Magento_Theme/js/view/messages': {
                'Bemeir_General/js/mixin/messages-mixin': true
            }
        }
    }
};

messages-mixin.js

define([
    'jquery',
    'uiComponent',
    'Magento_Customer/js/customer-data',
    'underscore',
    'jquery/jquery-storageapi'
], function ($, Component, customerData, _) {
    'use strict';
    return function (targetModule) {

        targetModule.defaults.isHidden = false;
        targetModule.defaults.listens.isHidden = 'onHiddenChange';
        targetModule.defaults.selector = '.page.messages .messages';

        return targetModule.extend({
            initialize: function () {
                let original = this._super();
                console.log(targetModule.defaults);
                return original;
            },
            initObservable: function () {
                this._super()
                    .observe('isHidden');

                return this;
            },

            isVisible: function () {
                return this.isHidden(!_.isEmpty(this.messages().messages) || !_.isEmpty(this.cookieMessages));
            },

            removeAll: function () {
                $(this.selector).find('.message').removeClass('show');
            },

            onHiddenChange: function (isHidden) {
                let self = this;
                if (isHidden) {
                    setTimeout(function () {
                        $(self.selector).find('.message').removeClass('show');
                        self.isHidden('false');
                    }, 5000);
                }
            }
        });
    };

});

Make sure to enlarge the timeout 5 secs it to low for customer to actually notice it and maybe click on the message etc.

Hope this will help someone. Also those who are interested please read this. https://alanstorm.com/magento-2-understanding-the-uielement-observe/

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.