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.
5 Answers
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.
-
-
Delete pub/static/*, clear cache. Run setup:static-content:deploy. Jan 30, 2017 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. Jan 30, 2017 at 7:33
-
For my case, I use SR_StackExchange is module name. And it's working fine with luma theme. Jan 30, 2017 at 7:50
-
1I 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. Jan 30, 2017 at 8:58
Please try the below solution and it works for me and I hope it will also work for you.
Please add the below code in the requirejs-config.js file to override the message js file.
var config = {
"map": {
"*": {
"Magento_Theme/js/view/messages": "Vendor_Module/js/view/messages",
}
}
}
Create a new message Js file in your module or you can also override directly by adding the same file in your theme directory.
Vendor/Module/view/frontend/web/js/view/messages.js
define([
'jquery',
'uiComponent',
'Magento_Customer/js/customer-data',
'underscore',
'escaper',
'jquery/jquery-storageapi'
], function ($, Component, customerData, _, escaper) {
'use strict';
return Component.extend({
defaults: {
cookieMessages: [],
messages: [],
allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']
},
/**
* Extends Component object by storage observable messages.
*/
initialize: function () {
this._super();
this.cookieMessages = _.unique($.cookieStorage.get('mage-messages'), 'text');
this.messages = customerData.get('messages').extend({
disposableCustomerData: 'messages'
});
// Force to clean obsolete messages
if (!_.isEmpty(this.messages().messages)) {
customerData.set('messages', {});
}
$.cookieStorage.set('mage-messages', '');
},
/**
* Prepare the given message to be rendered as HTML
*
* @param {String} message
* @return {String}
*/
prepareMessageForHtml: function (message) {
$(".messages").show();
setTimeout(function() {
$(".messages").hide('blind', {}, 500)
}, 5000);
return escaper.escapeHtml(message, this.allowedTags);
}
});
});
I have tested this in 2.3.5 and it seems to be working fine.
Please let me know if you need more details. Thanks.
Try this way.
requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Theme/js/view/messages': {
'[Your_Module]/js/view/messages-mixin': true
}
}
}
};
messages-mixin.js
define([
'underscore',
'Magento_Customer/js/customer-data'
], function (_, customerData) {
'use strict';
var mixin = {
initialize: function () {
this._super();
this.messages.subscribe(function (messages) {
if (_.isEmpty(messages.messages)) {
return;
}
setTimeout(function () {
customerData.set('messages', {});
}, 5000);
});
}
};
return function (target) {
return target.extend(mixin);
}
});
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);
// }
}
});
};
});
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/