Alert notifications are very common on websites, for example, when we want to give a message to the user, it is very useful. This message can be of any kind, for example, successful registration of a banking operation or a warning for a failed banking operation, The user can be sure that this message will disappear after a while and leaving the message on the page will not cause him any annoyance because some users are very disgusted with the messages remaining on the site page.
HTML
<!-- This script got from www.devanswer.com -->
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>
<div data-jc="toast" data-jc-config='timeout:6;format:dd\.MM\.yyyy hh\:mm;animate:fade;'></div>
<div class='container'>
<div class='row'>
<div class='col-md-10 center-block' style='float:none;'>
<div class="panel panel-default" style='margin: 20px 0; padding:10px;'>
<h4>Several Toast Notify with Time Bar</h4>
<div class='row'>
<div class='col-md-8'>
<div class="panel panel-default" style='margin: 20px 0; padding:10px;'>
Toast type events:<br>
<button data-bind="null__click:example" data-type='success' class='btn btn-default btn-sm'>Success</button>
<button data-bind="null__click:example" data-type='warning' class='btn btn-default btn-sm'>Warning</button>
<button data-bind="null__click:example" data-type='error' class='btn btn-default btn-sm'>Error</button>
<button data-bind="null__click:example" data-type='info' class='btn btn-default btn-sm'>Info</button>
<button data-bind="null__click:example" data-type='no' class='btn btn-default btn-sm'>No Type</button>
<hr>
Toast with date view:<br>
<button data-bind="null__click:example" data-type='success' data-day='-2' class='btn btn-default btn-sm'>Success with date (-2 days)</button>
<button data-bind="null__click:example" data-type='warning' data-day='-5' class='btn btn-default btn-sm'>Warning with date (-5 days)</button>
<button data-bind="null__click:example" data-type='error' data-day='0' class='btn btn-default btn-sm'>Error with date (current)</button>
<button data-bind="null__click:example" data-type='no' data-day='2' class='btn btn-default btn-sm'>No Type with date(+2 days)</button>
<hr>
Toast with with special icon:<br>
<button data-bind="null__click:example" data-type='success' data-day='-2' data-icon='thermometer-full' class='btn btn-default btn-sm'>Success with icon and date</button>
<button data-bind="null__click:example" data-type='no' data-icon='battery-quarter' class='btn btn-default btn-sm'>No Type with icon without date</button>
<hr>
Toast with with image:<br>
<button data-bind="null__click:example" data-type='error' data-img='test' data-day='2' class='btn btn-default btn-sm'>Error with date (current)</button>
<button data-bind="null__click:example" data-type='no' data-img='test' class='btn btn-default btn-sm'>No Type with icon without date</button>
<hr>
Toast with with special timeout:<br>
<button data-bind="null__click:example" data-type='success' data-day='2' data-timeout='10' class='btn btn-default btn-sm'>Success</button>
<button data-bind="null__click:example" data-type='no' data-icon='battery-quarter' data-timeout='15' class='btn btn-default btn-sm'>No Type with icon without date</button>
<hr>
Toast with callback:<br>
<button data-bind="null__click:example_callback" class='btn btn-default btn-sm'>Success</button>
</div>
</div>
<div class='col-md-4'>
<div class="panel panel-default" style='margin: 20px 0; padding:10px;'>
<b>Reconfigure</b><br><br>
Change position:<br>
<button data-bind="null__click:reconfigure" data-position='top-center' class='btn btn-default btn-sm'>top center</button>
<button data-bind="null__click:reconfigure" data-position='bottom-center' class='btn btn-default btn-sm'>bottom center</button>
<button data-bind="null__click:reconfigure" data-position='top-full-width' class='btn btn-default btn-sm'>top full width</button>
<button data-bind="null__click:reconfigure" data-position='bottom-full-width' class='btn btn-default btn-sm'>bottom full width</button>
<button data-bind="null__click:reconfigure" data-position='top-left' class='btn btn-default btn-sm'>top left</button>
<button data-bind="null__click:reconfigure" data-position='top-right' class='btn btn-default btn-sm'>top right</button>
<button data-bind="null__click:reconfigure" data-position='bottom-right' class='btn btn-default btn-sm'>bottom right</button>
<button data-bind="null__click:reconfigure" data-position='bottom-left' class='btn btn-default btn-sm'>bottom left</button>
<button data-bind="null__click:reconfigure" data-position='bottom-center' class='btn btn-default btn-sm'>bottom center</button>
<button data-bind="null__click:reconfigure" data-position='bottom-full-width' class='btn btn-default btn-sm'>bottom full width</button>
<hr>
Animate:<br>
<button data-bind="null__click:reconfigure" data-animate='fade' class='btn btn-default btn-sm'>fade</button>
<button data-bind="null__click:reconfigure" data-animate='slide' class='btn btn-default btn-sm'>slide</button>
<hr>
Loader:<br>
<button data-bind="null__click:reconfigure" data-loader='yes' class='btn btn-default btn-sm'>yes</button>
<button data-bind="null__click:reconfigure" data-loader='no' class='btn btn-default btn-sm'>no</button>
<hr>
Timeout view:<br>
<button data-bind="null__click:reconfigure" data-timeout='5' class='btn btn-default btn-sm'>5 sec</button>
<button data-bind="null__click:reconfigure" data-timeout='10' class='btn btn-default btn-sm'>10 sec</button>
<button data-bind="null__click:reconfigure" data-timeout='15' class='btn btn-default btn-sm'>15 sec</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script src='http://devanswer.com/codes/files/spa.min@18.js'></script><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Developers Answer</a></div>
CSS
/* Notifications */
.ui-toast-container {
position: fixed;
z-index: 10000;
padding: 5px 5px 0 0;
}
.ui-toast-container.top-center {
top: 0;
right: 0;
width: 100%
}
.ui-toast-container.bottom-center {
bottom: 0;
right: 0;
width: 100%
}
.ui-toast-container.top-full-width {
top: 0;
right: 0;
width: 100%
}
.ui-toast-container.bottom-full-width {
bottom: 0;
right: 0;
width: 100%
}
.ui-toast-container.top-left {
top: 12px;
left: 12px
}
.ui-toast-container.top-right {
top: 12px;
right: 12px
}
.ui-toast-container.bottom-right {
right: 12px;
bottom: 12px
}
.ui-toast-container.bottom-left {
bottom: 12px;
left: 12px
}
.ui-toast-container.bottom-center > div, .ui-toast-container.top-center > div {
width: 300px;
margin-left: auto;
margin-right: auto
}
.ui-toast-container.bottom-full-width > div, .ui-toast-container.top-full-width > div {
width: 96%;
margin-left: auto;
margin-right: auto
}
.ui-toast-container > div {
width: 300px;
}
.ui-toast {
background-color: white;
box-shadow: 0 0 3px #999;
border-radius: 3px;
font-size: 14px;
padding: 15px 15px 15px 10px;
margin: 0 0 6px;
position: relative;
display: flex;
opacity: .9;
}
.ui-toast .loader {
display: block;
width: 0%;
position: absolute;
left: 0;
bottom: 0;
height: 4px; /*background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)*/
}
.ui-toast .loaded {
width: 100%;
}
.ui-toast:hover {
-moz-box-shadow: 0 0 4px #999;
-webkit-box-shadow: 0 0 4px #999;
box-shadow: 0 0 4px #999;
opacity: 1;
-ms-filter: alpha(opacity=100);
filter: alpha(opacity=100);
}
.ui-toast > i {
position: absolute;
right: 12px;
top: 10px;
color: #AAB2BD;
font-size: 14px;
cursor: pointer;
text-shadow: 0 1px 0 #fff;
opacity: .8;
}
.ui-toast > i:active {
top: 11px;
}
.ui-toast > i:hover {
color: #000;
text-decoration: none;
cursor: pointer;
opacity: .4;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
filter: alpha(opacity=40)
}
.ui-toast-icon {
float: left;
font-size: 24px;
color: #AAB2BD;
line-height: 24px; /*padding-right:0.5em;*/
margin: auto 0.1em;
}
.ui-toast-message {
margin: 1px 0 0 10px;
color: gray;
max-height: 150px;
}
.ui-toast-datetime {
font-size: 10px;
color: #A0A0A0;
margin-bottom: 4px;
padding-top: 5px;
}
.ui-toast.success {
background-color: #1ab394;
}
.ui-toast.error {
background-color: #ed5565;
}
.ui-toast.info {
background-color: #2f96b4;
}
.ui-toast.warning {
background-color: #F89406;
}
.ui-toast.success > i, .ui-toast.error > i, .ui-toast.info > i, .ui-toast.warning > i {
color: #fff;
}
.ui-toast.success > i:hover, .ui-toast.error > i:hover, .ui-toast.info > i:hover, .ui-toast.warning > i:hover {
color: #000;
text-decoration: none;
opacity: .4;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
filter: alpha(opacity=40)
}
.ui-toast.success .ui-toast-icon, .ui-toast.error .ui-toast-icon, .ui-toast.info .ui-toast-icon, .ui-toast.warning .ui-toast-icon {
color: #fff;
}
.ui-toast.success .ui-toast-message, .ui-toast.error .ui-toast-message, .ui-toast.info .ui-toast-message, .ui-toast.warning .ui-toast-message {
color: #fff;
}
.ui-toast.success .ui-toast-datetime, .ui-toast.error .ui-toast-datetime, .ui-toast.info .ui-toast-datetime, .ui-toast.warning .ui-toast-datetime {
color: #F5F5F5;
}
{
color: #E0E0E0;
}
Javascript
COMPONENT('toast', 'timeout:8; position:top-right; loader:true; animate:fade', function (self, config) {
self.singleton();
self.readonly();
self.template = Tangular.compile('<div class="ui-toast {{ type }}" data-id="{{ id }}" {{ if callback }} style="cursor:pointer"{{ fi }}>{{ if loader }}<div class="loader"></div>{{fi}}<i class="fa fa-times"></i><div class="ui-toast-icon">{{if icon }}<i class="fa {{ icon }}"></i>{{fi}}{{if img }}{{ img | raw }}{{fi}}</div><div class="ui-toast-message">{{if date }}<div class="ui-toast-datetime">{{ date }}</div>{{fi}}{{ mess | raw }}</div></div>');
self.items = {};
self.make = function () {
self.aclass('ui-toast-container');
let position = config.position || 'top-right';
self.aclass(position);
self.event('click', 'a,button', function (e) {
e.stopPropagation();
});
self.event('click', '.ui-toast', function () {
var el = $(this);
var id = el.attr('data-id');
var obj = self.items[id];
self.close(obj.id);
});
};
self.configure = function (key, value, init, prev) {
if (init)
return;
if (key == 'position') {
self.rclass();
self.aclass('ui-toast-container ' + value);
}
}
self.close = function (id) {
var obj = self.items[id];
if (obj.autoClose) clearTimeout(obj.autoClose);
if (!obj) return;
if (obj.callback) obj.callback(obj);
obj.callback = null;
delete self.items[id];
if (config.animate == 'fade') {
self.find('div[data-id="{0}"]'.format(id)).fadeOut('normal', function () { $(this).remove() });
} else if (config.animate == 'slide') {
self.find('div[data-id="{0}"]'.format(id)).slideUp('normal', function () { $(this).remove() });
}
else {
self.find('div[data-id="{0}"]'.format(id)).remove();
}
};
self.success = function (mess, o, callback) {
self.append(mess, o, callback || null, 'success', 'check');
};
self.warning = function (mess, o, callback) {
self.append(mess, o, callback || null, 'warning', 'exclamation-triangle');
};
self.error = function (mess, o, callback) {
self.append(mess, o, callback || null, 'error', 'bell');
};
self.info = function (mess, o, callback) {
self.append(mess, o, callback || null, 'info', 'info-circle');
};
self.append = function (mess, o, callback, tp, ic) {
console.log(config);
if (typeof (o) === 'function') {
callback = o;
o = null;
}
if (!o) o = {};
o.type = o.type || tp || null;
o.icon = o.icon || ic || null;
let id = o.id || Math.floor(Math.random() * 100000);
let type = (o.type) ? o.type : '';
let icon = (o.icon) ? 'fa-' + o.icon : null;
let img = (o.img) ? "<img class='img-rounded img-responsive' src='" + o.img + "'>" : null;
let date = (o.date) ? o.date.format(config.format) : (config.dateAlways) ? new Date().format(config.format) : null;
var obj = { id: id, type: type, icon: icon, img: img, mess: mess, date: date, callback: callback };
obj.timeout = o.timeout || config.timeout;
if (obj.timeout) obj.timeout *= 1000;
obj.loader = o.loader || config.loader;
self.items[obj.id] = obj;
var elem = self.template(obj);
self.element.append(elem);
if (config.animate == 'fade') {
self.element.find('.ui-toast:last').hide().fadeIn();
} else if (config.animate == 'slide') {
self.element.find('.ui-toast:last').hide().slideDown();
}
if (obj.loader) {
self.updateLoader(obj);
}
if (obj.timeout) self.autoclose(obj);
};
self.updateLoader = function (obj) {
var el = self.find('.ui-toast[data-id="' + obj.id + '"] .loader');
var transitionTime = (obj.timeout / 1000) + 's';
var style = '';
style += '-webkit-transition: width ' + transitionTime + ' ease-in; \
-o-transition: width ' + transitionTime + ' ease-in; \
transition: width ' + transitionTime + ' ease-in; \
background-color: #000; \
opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40);';
el.attr('style', style);
setTimeout(function () { el.aclass('loaded'); }, 300);
};
self.autoclose = function (obj) {
obj.autoClose = setTimeout(function () {
self.close(obj.id);
}, obj.timeout);
};
})
//Test and example
var toast;
FIND('toast', function (comp) {
toast = comp;
});
function example(e) {
var str = [
'<b>Title</b><br>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod',
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod'
];
var ind = getRandom(2);
var options = {};
if (parseInt(e.data('day')) > -100) {
options.date = new Date().add(e.data('day') + ' day');
}
if (e.data('icon')) {
options.icon = e.data('icon');
}
if (e.data('img')) {
options.img = '#';
}
if (e.data('timeout')) {
options.timeout = e.data('timeout');
}
switch (e.data('type')) {
case 'success': toast.success(str[ind], options); break;
case 'warning': toast.warning(str[ind], options); break;
case 'error': toast.error(str[ind], options); break;
case 'info': toast.info(str[ind], options); break;
default: toast.append(str[ind], options);
}
}
function reconfigure(e) {
if (e.data('position')) {
RECONFIGURE('toast', { position: e.data('position') });
}
if (e.data('animate')) {
RECONFIGURE('toast', { animate: e.data('animate') });
}
if (e.data('loader')) {
var loader = (e.data('loader') == 'yes') ? true : false;
RECONFIGURE('toast', { loader: loader });
}
if (e.data('timeout')) {
RECONFIGURE('toast', { timeout: e.data('timeout') });
}
}
function example_callback(e) {
var str = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod';
toast.error(str, { 'icon': 'battery-empty' }, function (res) {
alert('Close notify - ' + res.mess);
});
}
function getRandom(max) {
return Math.floor(Math.random() * Math.floor(max));
}