Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save anonymous/11155440 to your computer and use it in GitHub Desktop.
Save anonymous/11155440 to your computer and use it in GitHub Desktop.
A Pen by Captain Anonymous.

AngularJS / Bootstrap 3 / jQuery "Growl" Directive v1.1

AngularJS / Bootstrap 3 / jQuery "Growl" Directive v1.1

This version uses jQuery for the fadeOut and Bootstrap for the demo.

A Pen by Captain Anonymous on CodePen.

License.

<head>
<!-- jQuery -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js'></script>
<link rel='stylesheet prefetch' href='http://netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css'>
</head>
<body ng-app="myApp" ng-controller="myController">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{title}}</h3>
</div>
<div class="panel-body">
<p>
These are the four types of "growls":
</p>
<p>
<span ng-repeat="item in types"><button class="btn btn-{{item}}" ng-click="growlAdd(item)" data-test="test">{{item | capitalize}}</button></span>
</p>
<p>
Timeout (ttl): <input ng-model="ttl" /><br/>
</p>
<p>
Position: <input ng-model="position" /><br/>
</p>
<p>
Text: <input ng-model="text" /><br/>
</p>
<p>
<ul>
<h4>Required for Release</h4>
<li class="done">popup "growl" with id, type, title, text √</li>
<li class="done">click-to-close: entire element or (x) √</li>
<li class="done">ttl timeout √</li>
<li class="done">settable text √</li>
<h4>Extras</h4>
<li class="done">four positions √</li>
<li>fadeOut/fadeIn (switching to css animation)</li>
<li>default bootstrap + custom styles</li>
<li>http intercept to auto show server messages</li>
</ul>
</p>
<h4>Growl Queue</h4>
<pre>
{{growls}}
</pre>
<span><button class="btn" ng-click="clear()">Clear Messages</button></span>
<!-- growls container grows with content -->
<div growls-container id="growls-container" class="{{position}}"></div>
</div>
</div>
</body>
var lb = "• ";
var myApp = angular.module("myApp", []);
myApp.controller('myController', function($scope, $timeout) {
$scope.title = 'AngularJS / Bootstrap 3 "Growl" Directive v1.1';
$scope.types = ["success", "info", "warning", "danger"];
$scope.growlsClear = function (){
$scope.growls = [];
};
$scope.growlsClear();
// defaults
$scope.ttl = 3000;
$scope.position = "bottom-right";
$scope.text = "sample text";
// Add
$scope.growlAdd = function(){
//console.log(this);
var gid = $scope.growls.length + 1;
var type = this.item;
var title = this.item;
var text = $scope.text;
var item = {gid:gid, type:type, title:title, text:text};
$scope.growls.push(item);
console.log(lb + "added " + type + " growl with gid " + gid)
};
// Remove
$scope.growlRemove = function(gid) {
console.log(lb + 'growlRemove in controller removing gid ' + gid);
for (var i=0; i < $scope.growls.length; i++){
if ($scope.growls[i].gid == gid) {
$scope.growls.splice(i,1);
break;
}
}
};
});
myApp.directive('growlsContainer', function() {
return {
template: [
' <div growl-item class="growl-item {{growl.type}}" ng-repeat="growl in growls" data-gid="{{growl.gid}}">',
' <div class="growl-content">',
' <h4>{{growl.title | capitalize}}</h4>',
' <p>{{growl.text}}</p>',
' </div>',
' <div class="growl-close" data-gid="{{growl.gid}}""></div>',
' </div>'
].join('\n'),
};
});
myApp.directive("growlItem", function($timeout) {
return function($scope, $element, $attrs) {
var gid = $attrs.gid;
function growlFadeOut(gid){
$($element).fadeOut(1000, function() {
console.log(lb + "growlFadeOut completed in directive calling growlRemove gid " + gid);
/* MUST wrap this in apply or digest will not happen */
$scope.$apply( function(){
$scope.growlRemove(gid);
});
});
};
$element.bind("click", function() {
console.log(lb + "click fading gid: "+ gid);
growlFadeOut(gid);
});
var promise = $timeout(function(){
console.log(lb + 'timeout fading gid ' + gid);
growlFadeOut(gid);
},$scope.ttl);
$element.bind('$destroy', function() {
if(promise){
console.log(lb + 'cancelling timeout for gid ' + gid)
//console.log(promise);
var cancelled = $timeout.cancel(promise) ? "timeout cancel success for gid " + gid : "timeout already expired for gid " + gid;
console.log(lb + cancelled);
};
});
};
});
myApp.filter('capitalize', function() {
return function(input, scope) {
if (input!=null){
return input.substring(0,1).toUpperCase()+input.substring(1);
}
}
});
.panel {
width:80%;
margin:2em auto;
}
p {
padding:1em 1em 1em 1em ;
}
span {
margin:4px;
}
input {
float:right;
width:50%;
}
.done{
font-weight:bold;
}
.growl-item p {
padding:0;
}
.top-left { top: 10px; left: 15px; }
.top-right { top: 10px; right: 15px; }
.bottom-left { bottom: 10px; left: 15px; }
.bottom-right { bottom: 10px; right: 15px; }
#growls-container {
width:300px;
position:fixed;
}
.growl-item {
background: #DDD;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #F9F9F9), color-stop(1, #D5D5D5));
background: -moz-linear-gradient(top, #F9F9F9, #D5D5D5);
background: -o-linear-gradient(#F9F9F9, #D5D5D5);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F9F9F9', endColorstr='#D5D5D5');
width: 300px;
font-size: 11px;
color: #333;
padding: 0;
margin: 0 0 10px 0;
border: 1px solid #A8A8A8;
position: relative;
-webkit-box-shadow: 0 0 7px rgba(0,0,0,.3);
-moz-box-shadow: 0 0 7px rgba(0,0,0,.3);
-o-box-shadow: 0 0 7px rgba(0,0,0,.3);
box-shadow: 0 0 7px rgba(0,0,0,.3);
-webkit-text-shadow: 0 0 1px #FFF;
-moz-text-shadow: 0 0 1px #FFF;
-o-text-shadow: 0 0 1px #FFF;
text-shadow: 0 0 1px #FFF;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
.growl-content h4 {
font-weight:bold;
font-size: 12px;
color: #333;
margin-bottom: .5em;
-webkit-text-shadow: 0 0 1px #FFF;
-moz-text-shadow: 0 0 1px #FFF;
-o-text-shadow: 0 0 1px #FFF;
text-shadow: 0 0 1px #FFF;
}
.growl-content { padding: 10px 20px 10px 10px; }
.growl-close:hover { opacity: 1; cursor: pointer; }
.growl-close {
background: url(http://paulbhartzog.org/codepen/msgGrowl_close.png) no-repeat 50% 50%;
width: 11px;
height: 10px;
position: absolute;
top: 10px;
right: 10px;
opacity: .4;
border:1px solid gray;
padding:5px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px;
}
.growl-item.success .growl-content { background: url(http://paulbhartzog.org/codepen/growl_success.png) no-repeat 10px 13px; }
.growl-item.success .growl-content { padding-left: 50px; }
.growl-item.success h4 { color: #5B7027; }
.growl-item.danger .growl-content { background: url(http://paulbhartzog.org/codepen/growl_danger.png) no-repeat 10px 13px; }
.growl-item.danger .growl-content { padding-left: 50px; }
.growl-item.danger h4 { color: #AF4434; }
.growl-item.info .growl-content { background: url(http://paulbhartzog.org/codepen/growl_info.png) no-repeat 10px 13px; }
.growl-item.info .growl-content { padding-left: 50px; }
.growl-item.info h4 { color: #316AB7; }
.growl-item.warning .growl-content { background: url(http://paulbhartzog.org/codepen/growl_warning.png) no-repeat 10px 13px; }
.growl-item.warning .growl-content { padding-left: 50px; }
.growl-item.warning h4 { color: #B69201; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment