This widget creates a growl-like notification on a website using CanJS framework.
JavaScript
steal('can/construct',
'can/construct/super',
'can/construct/proxy',
'can/control',
'can/view/ejs',
'./growl.less',
'./views/growl.ejs',
function(){
/**
* `can.ui.notify` is a system for creating notifications.
*/
can.Construct("can.ui.notify", {
defaults:{
time: 1500,
position: "bottom right",
animate: 'fade',
sticky: true,
template: '//canui/growl/views/growl.ejs',
dismissable: false,
dismissText: "Dismiss"
},
queue: [],
counter: 0,
init:function(options){
this.defaults = can.extend(this.defaults, options || {});
this.wrapper = $('<div class="notification-wrapper ' +
this.defaults.position.split(' ').join('-') + '" />').appendTo(document.body);
},
/**
* Adds a notification to the screen.
*
* For example:
* {
* title: "Tip",
* image: "",
* text: "Click and hold for a moment to pan."
* }
*
* Additionally, you can pass any arguments that are
* included in the defaults to override a particular
* action.
*
* @param {[type]} note
*/
add: function(note){
this.queue.push(new mj.notify.Bubble(this.wrapper,
can.extend(this.defaults, note || {}, { id: this.counter++ })));
},
/**
* Dismisses a single notification by `id`.
* @param {Number} id
*/
dismiss:function(id){
$.each(this.queue, function(bubble, i){
if(bubble.id === id){
bubble.dismiss();
}
});
},
/**
* Dismisses all notifications.
*/
dismissAll:function(){
$.each(this.queue, function(bubble, i){
bubble.dismiss();
});
}
},{});
/**
* Bubbles are the notifications themselves.
*/
can.Control('can.notify.Bubble',{
setup:function(el,options){
this.id = options.id;
this._super($(can.view.render(options.template, options))
.appendTo(el), options);
},
init:function(){
this.element[this.options.animate + "In"]();
this.startTimer();
},
startTimer:function(){
if(!this.options.sticky){
this.timer = setTimeout(this.proxy('dismiss'), this.options.time);
}
},
dismiss:function(){
this.element[this.options.animate + "Out"]();
},
" click": "dismiss",
" mouseenter":function(elm,ev){
clearTimeout(this.timer);
},
" mouseleave": "startTimer",
".dismiss click": "dismiss"
});
});
LESS
.notification-wrapper{
position:fixed;
z-index:9999;
&.top-right{
top:20px;
right:20px;
}
&.top-left {
left: 20px;
right: auto;
}
&.bottom-right {
top: auto;
left: auto;
bottom: 20px;
right: 20px;
}
&.bottom-left {
top: auto;
right: auto;
bottom: 20px;
left: 20px;
}
}
.notification{
color: #eee;
padding:8px 11px;
background:#000;
cursor:pointer;
display:none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
opacity: 0.7;
filter: alpha(opacity=70);
&:hover{
opacity: 1;
filter: alpha(opacity=100);
}
.image{
float:left;
}
h2{
margin:0;
font-size: 14px;
font-weight: bold;
padding: 0 0 5px 0;
display: block;
text-shadow: 1px 1px 0 #000;
}
p{
padding:0;
margin:0;
font-size: 11px;
}
.dismiss{
padding-top:5px;
color:#FFF;
text-decoration: none;
font-size:10px;
}
}
EJS
<div class="notification">
<% if(this.image){ %>
<img class="image" src="<%== this.image %>" />
<% } %>
<% if(this.header){ %>
<h2><%== this.header %></h2>
<% } %>
<% if(this.text){ %>
<p><%== this.text %></p>
<% } %>
<% if(this.dismissable) { %>
<a class="dismiss" href="#"><%== this.dismissText %></a>
<% } %>
</div>
HTML
<script type='text/javascript'>
steal('can/ui/growl').then(function($, Control){
can.ui.notify.add({
header: "Amazing things",
text: "Click and hold down your mouse for a moment to pan."
});
})
</script>