├── .bowerrc ├── .editorconfig ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── bower.json ├── dist ├── angular-growl-notifications.js └── angular-growl-notifications.min.js ├── package.json ├── readme.md ├── src └── growlNotifications │ ├── directives │ ├── growlNotification.js │ └── growlNotifications.js │ ├── growlNotifications.js │ └── services │ └── growlNotifications.js └── test └── unit └── growlNotifications ├── directive └── growlNotificationSpec.js ├── growlNotificationsSpec.js └── services └── growlNotificationsSpec.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower" 3 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ._* 2 | .~lock.* 3 | .buildpath 4 | .DS_Store 5 | .idea 6 | .project 7 | .settings 8 | 9 | # Ignore node stuff 10 | node_modules/ 11 | npm-debug.log 12 | libpeerconnection.log 13 | 14 | # OS-specific 15 | .DS_Store 16 | 17 | # Bower components 18 | bower 19 | 20 | # Harp files 21 | _harp -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "es5": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 4, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "white": true 22 | } 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | before_script: 6 | - npm install -qg bower grunt-cli 7 | - npm install 8 | - bower install -F 9 | 10 | script: 11 | - grunt 12 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | require('load-grunt-tasks')(grunt); 4 | 5 | grunt.initConfig({ 6 | 7 | pkg: grunt.file.readJSON('package.json'), 8 | 9 | concat: { 10 | options: { 11 | separator: '' 12 | }, 13 | library: { 14 | src: [ 15 | 'src/growlNotifications/growlNotifications.js', 16 | 'src/growlNotifications/directives/**/*.js', 17 | 'src/growlNotifications/services/**/*.js' 18 | ], 19 | dest: 'dist/angular-growl-notifications.js' 20 | } 21 | }, 22 | 23 | uglify: { 24 | options: { 25 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' 26 | }, 27 | library: { 28 | files: { 29 | 'dist/angular-growl-notifications.min.js': ['<%= concat.library.dest %>'] 30 | } 31 | } 32 | }, 33 | 34 | jshint: { 35 | beforeConcat: { 36 | src: ['gruntfile.js', 'growlNotifications/**/*.js'] 37 | }, 38 | afterConcat: { 39 | src: [ 40 | '<%= concat.library.dest %>' 41 | ] 42 | }, 43 | options: { 44 | // options here to override JSHint defaults 45 | globals: { 46 | jQuery: true, 47 | console: true, 48 | module: true, 49 | document: true, 50 | angular: true 51 | }, 52 | globalstrict: false 53 | } 54 | }, 55 | 56 | watch: { 57 | options: { 58 | livereload: true 59 | }, 60 | files: [ 61 | 'Gruntfile.js', 62 | 'src/**/*' 63 | ], 64 | tasks: ['default'] 65 | } 66 | 67 | }); 68 | 69 | grunt.registerTask('default', ['jshint:beforeConcat', 'concat', 'jshint:afterConcat', 'uglify']); 70 | grunt.registerTask('livereload', ['default', 'watch']); 71 | 72 | }; 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 Jurgen Van de Moere 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-growl-notifications", 3 | "version": "2.6.0", 4 | "main": [ 5 | "dist/angular-growl-notifications.js" 6 | ], 7 | "keywords": [ 8 | "angular", 9 | "angularjs", 10 | "growl", 11 | "notification", 12 | "notifications" 13 | ], 14 | "authors": [ 15 | { 16 | "name": "Jurgen Van de Moere", 17 | "email": "jurgen.van.de.moere@gmail.com", 18 | "homepage": "http://www.jvandemo.com" 19 | } 20 | ], 21 | "ignore": [ 22 | "src", 23 | "test", 24 | ".bowerrc", 25 | ".editorconfig", 26 | ".gitignore", 27 | ".jshintrc", 28 | ".travis.yml", 29 | "Gruntfile.js", 30 | "package.json" 31 | ], 32 | "repository": { 33 | "type": "git", 34 | "url": "git://github.com/jvandemo/angular-growl-notifications.git" 35 | }, 36 | "dependencies": { 37 | "angular": ">=1.2.22 <2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dist/angular-growl-notifications.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // Config 4 | angular.module('growlNotifications.config', []) 5 | .value('growlNotifications.config', { 6 | debug: true 7 | }); 8 | 9 | // Modules 10 | angular.module('growlNotifications.directives', []); 11 | angular.module('growlNotifications.filters', []); 12 | angular.module('growlNotifications.services', []); 13 | angular.module('growlNotifications', 14 | [ 15 | 'growlNotifications.config', 16 | 'growlNotifications.directives', 17 | 'growlNotifications.filters', 18 | 'growlNotifications.services' 19 | ]); 20 | 21 | })(); 22 | (function () { 23 | 24 | function growlNotificationDirective(growlNotifications, $animate, $interval) { 25 | 26 | var defaults = { 27 | ttl: growlNotifications.options.ttl || 5000 28 | }; 29 | 30 | return { 31 | 32 | /** 33 | * Allow compilation via attributes as well so custom 34 | * markup can be used 35 | */ 36 | restrict: 'AE', 37 | 38 | /** 39 | * Create new child scope 40 | */ 41 | scope: true, 42 | 43 | /** 44 | * Controller 45 | */ 46 | controller: growlNotificationController, 47 | 48 | /** 49 | * Make the controller available in the directive scope 50 | */ 51 | controllerAs: '$growlNotification', 52 | 53 | /** 54 | * Post link function 55 | * 56 | * @param scope 57 | * @param iElem 58 | * @param iAttrs 59 | * @param ctrl 60 | */ 61 | link: function (scope, iElem, iAttrs, ctrl) { 62 | 63 | // Assemble options 64 | var options = angular.extend({}, defaults, scope.$eval(iAttrs.growlNotificationOptions)); 65 | 66 | // The number of times the notification timeout method should be run 67 | // This should always be set to 1 to emulate $timeout 68 | var REPEAT_COUNT = 1; 69 | 70 | if (iAttrs.ttl) { 71 | options.ttl = scope.$eval(iAttrs.ttl); 72 | } 73 | 74 | // Move the element to the right location in the DOM 75 | $animate.move(iElem, growlNotifications.element); 76 | 77 | // Run onOpen handler if there is one 78 | if (iAttrs.onOpen) { 79 | scope.$eval(iAttrs.onOpen); 80 | } 81 | 82 | // Schedule automatic removal unless ttl set to false/-1 83 | if(options.ttl !== -1 && options.ttl !== false) { 84 | ctrl.timer = $interval(function () { 85 | $animate.leave(iElem); 86 | 87 | // Run onClose handler if there is one 88 | if(iAttrs.onClose){ 89 | scope.$eval(iAttrs.onClose); 90 | } 91 | }, options.ttl, REPEAT_COUNT); 92 | } 93 | 94 | } 95 | }; 96 | 97 | } 98 | 99 | // Inject dependencies 100 | growlNotificationDirective.$inject = ['growlNotifications', '$animate', '$interval']; 101 | 102 | /** 103 | * Directive controller 104 | * 105 | * @param $element 106 | * @param $animate 107 | * @param $attrs 108 | * @param $scope 109 | */ 110 | function growlNotificationController($element, $animate, $attrs, $scope, $interval) { 111 | 112 | /** 113 | * Placeholder for timer promise 114 | */ 115 | this.timer = null; 116 | 117 | /** 118 | * Helper method to close notification manually 119 | */ 120 | this.remove = function () { 121 | 122 | // Remove the element 123 | $animate.leave($element); 124 | 125 | // Cancel scheduled automatic removal if there is one 126 | if (this.timer) { 127 | $interval.cancel(this.timer); 128 | 129 | // Run onClose handler if there is one 130 | if($attrs.onClose){ 131 | $scope.$eval($attrs.onClose); 132 | } 133 | } 134 | }; 135 | 136 | } 137 | 138 | // Inject dependencies 139 | growlNotificationController.$inject = ['$element', '$animate', '$attrs', '$scope', '$interval']; 140 | 141 | // Export 142 | angular 143 | .module('growlNotifications.directives') 144 | .directive('growlNotification', growlNotificationDirective); 145 | 146 | })(); 147 | (function () { 148 | 149 | /** 150 | * Create directive definition object 151 | * 152 | * @param growlNotifications 153 | */ 154 | function growlNotificationsDirective(growlNotifications) { 155 | 156 | return { 157 | 158 | /** 159 | * Allow compilation via attributes as well so custom 160 | * markup can be used 161 | */ 162 | restrict: 'AE', 163 | 164 | /** 165 | * Post link function 166 | * 167 | * @param scope 168 | * @param iElem 169 | * @param iAttrs 170 | */ 171 | link: function (scope, iElem, iAttrs) { 172 | growlNotifications.element = iElem; 173 | } 174 | }; 175 | 176 | } 177 | 178 | // Inject dependencies 179 | growlNotificationsDirective.$inject = ['growlNotifications']; 180 | 181 | // Export 182 | angular 183 | .module('growlNotifications.directives') 184 | .directive('growlNotifications', growlNotificationsDirective); 185 | 186 | })();(function () { 187 | 188 | /** 189 | * Growl notifications provider 190 | */ 191 | function growlNotificationsProvider() { 192 | 193 | // Default options 194 | var options = { 195 | ttl: 5000 196 | }; 197 | 198 | /** 199 | * Provider method to change default options 200 | * 201 | * @param newOptions 202 | */ 203 | this.setOptions = function (newOptions) { 204 | angular.extend(options, newOptions); 205 | return this; 206 | }; 207 | 208 | /** 209 | * Provider convenience method to get or set default ttl 210 | * 211 | * @param ttl 212 | * @returns {*} 213 | */ 214 | this.ttl = function (ttl) { 215 | if (angular.isDefined(ttl)) { 216 | options.ttl = ttl; 217 | return this; 218 | } 219 | return options.ttl; 220 | }; 221 | 222 | /** 223 | * Factory method 224 | * 225 | * @param $timeout 226 | * @param $rootScope 227 | * @returns {GrowlNotifications} 228 | */ 229 | this.$get = function () { 230 | 231 | function GrowlNotifications() { 232 | 233 | this.options = options; 234 | this.element = null; 235 | 236 | } 237 | 238 | return new GrowlNotifications(); 239 | 240 | }; 241 | 242 | } 243 | 244 | // Export 245 | angular 246 | .module('growlNotifications.services') 247 | .provider('growlNotifications', growlNotificationsProvider); 248 | 249 | })(); 250 | -------------------------------------------------------------------------------- /dist/angular-growl-notifications.min.js: -------------------------------------------------------------------------------- 1 | /*! angular-growl-notifications 08-03-2017 */ 2 | !function(){angular.module("growlNotifications.config",[]).value("growlNotifications.config",{debug:!0}),angular.module("growlNotifications.directives",[]),angular.module("growlNotifications.filters",[]),angular.module("growlNotifications.services",[]),angular.module("growlNotifications",["growlNotifications.config","growlNotifications.directives","growlNotifications.filters","growlNotifications.services"])}(),function(){function a(a,c,d){var e={ttl:a.options.ttl||5e3};return{restrict:"AE",scope:!0,controller:b,controllerAs:"$growlNotification",link:function(b,f,g,h){var i=angular.extend({},e,b.$eval(g.growlNotificationOptions)),j=1;g.ttl&&(i.ttl=b.$eval(g.ttl)),c.move(f,a.element),g.onOpen&&b.$eval(g.onOpen),-1!==i.ttl&&i.ttl!==!1&&(h.timer=d(function(){c.leave(f),g.onClose&&b.$eval(g.onClose)},i.ttl,j))}}}function b(a,b,c,d,e){this.timer=null,this.remove=function(){b.leave(a),this.timer&&(e.cancel(this.timer),c.onClose&&d.$eval(c.onClose))}}a.$inject=["growlNotifications","$animate","$interval"],b.$inject=["$element","$animate","$attrs","$scope","$interval"],angular.module("growlNotifications.directives").directive("growlNotification",a)}(),function(){function a(a){return{restrict:"AE",link:function(b,c,d){a.element=c}}}a.$inject=["growlNotifications"],angular.module("growlNotifications.directives").directive("growlNotifications",a)}(),function(){function a(){var a={ttl:5e3};this.setOptions=function(b){return angular.extend(a,b),this},this.ttl=function(b){return angular.isDefined(b)?(a.ttl=b,this):a.ttl},this.$get=function(){function b(){this.options=a,this.element=null}return new b}}angular.module("growlNotifications.services").provider("growlNotifications",a)}(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-growl-notifications", 3 | "version": "2.6.0", 4 | "keywords": [ 5 | "angular", 6 | "angularjs", 7 | "growl", 8 | "notification", 9 | "notifications" 10 | ], 11 | "main": "./dist/angular-growl-notifications.js", 12 | "author": { 13 | "name": "Jurgen Van de Moere", 14 | "email": "jurgen.van.de.moere@gmail.com", 15 | "url": "http://www.jvandemo.com" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "http://github.com/jvandemo/angular-growl-notifications.git" 20 | }, 21 | "dependencies": { 22 | "angular": ">=1.2.22 <2" 23 | }, 24 | "devDependencies": { 25 | "grunt": "~0.4.1", 26 | "grunt-contrib-concat": "~0.3.0", 27 | "grunt-contrib-jshint": "~0.7.0", 28 | "grunt-contrib-uglify": "~0.2.0", 29 | "grunt-contrib-watch": "~0.5.0", 30 | "grunt-karma": "~0.8.0", 31 | "karma": "~0.12.0", 32 | "karma-chrome-launcher": "~0.1.0", 33 | "karma-phantomjs-launcher": "~0.1.0", 34 | "load-grunt-tasks": "^0.6.0", 35 | "karma-mocha": "^0.1.7" 36 | }, 37 | "engines": { 38 | "node": ">=0.8.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![AngularJS Growl Notifications](http://i.imgur.com/F4ttQxo.png) 2 | 3 | # Growl notifications for AngularJS 4 | [![Build Status](https://travis-ci.org/jvandemo/angular-growl-notifications.png?branch=master)](https://travis-ci.org/jvandemo/angular-growl-notifications) 5 | 6 | Notifications logically belong inside the view layer of your application. 7 | 8 | Most existing growl systems require you to add notifications using JavaScript inside your controller layer. 9 | 10 | This very lightweight library (<2KB) allows you to declaratively create notifications using directives only, supporting both inline expressions and HTML. 11 | 12 | Think Growl, but in AngularJS directives. Oh, and Bootstrap compatible too. 13 | 14 | - [Visit the official website](http://jvandemo.github.io/angular-growl-notifications/) 15 | - [View live examples](http://jvandemo.github.io/angular-growl-notifications/examples/) 16 | - [Read the complete documentation](http://jvandemo.github.io/angular-growl-notifications/docs/) 17 | 18 | [![Official website](http://i.imgur.com/tB1FvX7.png)](http://jvandemo.github.io/angular-growl-notifications/) 19 | 20 | # Quick start 21 | 22 | Learn how to create Mac OS X like pop-up notifications in your AngularJS application. 23 | 24 | ### STEP 1: Install the library 25 | 26 | Download the code from [GitHub](https://github.com/jvandemo/angular-growl-notifications) or install it using bower: 27 | 28 | ```sh 29 | $ bower install angular-growl-notifications 30 | ``` 31 | 32 | Load the library in your markup: 33 | 34 | ```html 35 | 36 | 37 | ``` 38 | 39 | Load the `growlNotifications` module in your AngularJS application: 40 | 41 | ```javascript 42 | angular.module('yourApp', ['growlNotifications']); 43 | ``` 44 | 45 | The library is now loaded in your AngularJS application. 46 | 47 | ### STEP 2: Specify where you want to render the notifications 48 | 49 | Before you can create notifications, you need to add the `growl-notifications` (plural) directive to your markup. 50 | 51 | This directive allows you to control where the notifications are rendered in your DOM in case your application requires special behavior. 52 | 53 | In most cases you should simply add it as the first element inside the `body` element: 54 | 55 | ```html 56 | 57 | 58 | 59 | ... 60 | 61 | ``` 62 | 63 | Check out the [growl-notifications directive documentation](http://jvandemo.github.io/angular-growl-notifications/docs/directives/growl-notifications) for more information. 64 | 65 | ### STEP 3: Create notifications 66 | 67 | You can now use the `growl-notification` (singular) directive to create notifications anywhere in your application: 68 | 69 | ```html 70 | 71 | 72 | Hello world 73 | 74 | ``` 75 | 76 | You can use AngularJS expressions: 77 | 78 | ```html 79 | 80 | 81 | Hello {{name}} 82 | 83 | ``` 84 | 85 | and HTML: 86 | 87 | ```html 88 | 89 | 90 | Hello {{name}} 91 | 92 | ``` 93 | 94 | Most of the time you will want to show a notification when some event occurs. You can use the native AngularJS `ng-if` directive to make this happen: 95 | 96 | ```html 97 | 98 | 99 | showNotification just became truthy 100 | 101 | ``` 102 | 103 | By default notifications are shown for 5 seconds, but you can specify the `ttl` in milliseconds for every notification individually: 104 | 105 | ```html 106 | 107 | Only show me for 1000ms 108 | 109 | ``` 110 | 111 | A `ttl` of `-1` or `false` will disable the automatic closing timeout, making the notification permanent. You will need to close the notification manually using `$growlNotification.remove()`. 112 | 113 | You can also specify handlers you wish to run when the notification opens and closes: 114 | 115 | ```html 116 | 117 | ... 118 | 119 | ``` 120 | 121 | which is convenient if you want to auto-reset some state when the notification is closed: 122 | 123 | ```html 124 | 125 | 126 | 127 | 128 | 129 | ... 130 | 131 | ``` 132 | 133 | Check out the [growl-notification directive documentation](http://jvandemo.github.io/angular-growl-notifications/docs/directives/growl-notification) for all available options. 134 | 135 | ### STEP 4: Customize look and feel 136 | 137 | By default no styling is applied so you can completely control the look and feel of the notifications in your application's stylesheet. 138 | 139 | The possibilities are endless, for example to display notifications in the top right of your page: 140 | 141 | ```css 142 | growl-notifications{ 143 | position: fixed; 144 | top: 150px; 145 | right: 10px; 146 | } 147 | growl-notification{ 148 | border: 1px solid black; 149 | padding: 15px 30px; 150 | margin-bottom: 15px; 151 | } 152 | ``` 153 | 154 | ### That's it 155 | 156 | ![Hello world](http://i.imgur.com/T4Z2KPj.gif) 157 | 158 | You now have a working notification system in your AngularJS application. 159 | 160 | When you load the page, a "Hello world" notification will automatically appear and disappear. 161 | 162 | There are many additional features and options, so make sure to visit the [examples page](http://jvandemo.github.io/angular-growl-notifications/examples) for more inspiration and sample code. 163 | 164 | ### Manually closing notification after a UI-Router state change 165 | 166 | If you find yourself in a rare situation where you need to manually close a notification after a state change, you can create a custom directive as demonstrated in [this plunk](https://plnkr.co/edit/4j9pivI7bBuCVy8QQ2zK?p=preview) and discussed in [this thread](https://github.com/jvandemo/angular-growl-notifications/issues/25). 167 | 168 | ## License 169 | 170 | MIT 171 | 172 | ## Change log 173 | 174 | ### v2.5.1 175 | 176 | - Added support for permanent notifications. Setting `ttl` to `-1` or `false` will keep notifications visible until manually closed (e.g with `$growlNotification.remove()`); 177 | 178 | ### v2.6.0 179 | 180 | - Add support for infinite notification (#31) 181 | 182 | ### v2.5.0 183 | 184 | - Replace $timeout with $interval to fix #28 185 | 186 | ### v2.4.0 187 | 188 | - Updated timeout cancel mechanism (#27) 189 | 190 | ### v2.3.0 191 | 192 | - Updated angular dependency version (#22) 193 | 194 | ### v2.2.0 195 | 196 | - Added support for `on-open` handler 197 | - Added support for `on-close` handler 198 | - Updated documentation 199 | 200 | ### v2.1.2 201 | 202 | - Make angular dependency version less strict 203 | 204 | ### v2.1.1 205 | 206 | - Fix issue with injection of `$animate` in controller of `growlNotification` directive 207 | 208 | ### v2.1.0 209 | 210 | - Update code to follow the [AngularJS styleguide](https://github.com/toddmotto/angularjs-styleguide) principles 211 | 212 | ### v2.0.1 213 | 214 | - Fix issue with minification of controller in `growlNotification` directive (see [this issue](https://github.com/jvandemo/angular-growl-notifications/issues/3)). 215 | 216 | ### v2.0.0 217 | 218 | - Directives have been rewritten for better performance 219 | - Now supports manually closing notifications using markup 220 | - v1 release has been moved to v1.x.x branch 221 | 222 | ### v0.7.0 223 | 224 | - Added support for custom css prefix (defaults to Bootstrap alert) 225 | 226 | ### v0.6.0 227 | 228 | - The growl-notifications directive now uses an isolate scope 229 | 230 | ### v0.5.0 231 | 232 | - Added support for custom options in growl-notification directive 233 | - Updated demo page 234 | 235 | ### v0.4.0 236 | 237 | - Added $animate support 238 | - Updated demo page 239 | 240 | ### v0.3.0 241 | 242 | - Added dist directory with pre-built library files 243 | - Added demo page 244 | 245 | ### v0.2.0 246 | 247 | - Added `growl-notification` directive to conveniently add notifications from within HTML markup 248 | - Added `growl-notifications` directive to conveniently display notifications from within HTML markup 249 | - Added documentation 250 | 251 | ### v0.1.0 252 | 253 | - Initial version 254 | -------------------------------------------------------------------------------- /src/growlNotifications/directives/growlNotification.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function growlNotificationDirective(growlNotifications, $animate, $interval) { 4 | 5 | var defaults = { 6 | ttl: growlNotifications.options.ttl || 5000 7 | }; 8 | 9 | return { 10 | 11 | /** 12 | * Allow compilation via attributes as well so custom 13 | * markup can be used 14 | */ 15 | restrict: 'AE', 16 | 17 | /** 18 | * Create new child scope 19 | */ 20 | scope: true, 21 | 22 | /** 23 | * Controller 24 | */ 25 | controller: growlNotificationController, 26 | 27 | /** 28 | * Make the controller available in the directive scope 29 | */ 30 | controllerAs: '$growlNotification', 31 | 32 | /** 33 | * Post link function 34 | * 35 | * @param scope 36 | * @param iElem 37 | * @param iAttrs 38 | * @param ctrl 39 | */ 40 | link: function (scope, iElem, iAttrs, ctrl) { 41 | 42 | // Assemble options 43 | var options = angular.extend({}, defaults, scope.$eval(iAttrs.growlNotificationOptions)); 44 | 45 | // The number of times the notification timeout method should be run 46 | // This should always be set to 1 to emulate $timeout 47 | var REPEAT_COUNT = 1; 48 | 49 | if (iAttrs.ttl) { 50 | options.ttl = scope.$eval(iAttrs.ttl); 51 | } 52 | 53 | // Move the element to the right location in the DOM 54 | $animate.move(iElem, growlNotifications.element); 55 | 56 | // Run onOpen handler if there is one 57 | if (iAttrs.onOpen) { 58 | scope.$eval(iAttrs.onOpen); 59 | } 60 | 61 | // Schedule automatic removal unless ttl set to false/-1 62 | if(options.ttl !== -1 && options.ttl !== false) { 63 | ctrl.timer = $interval(function () { 64 | $animate.leave(iElem); 65 | 66 | // Run onClose handler if there is one 67 | if(iAttrs.onClose){ 68 | scope.$eval(iAttrs.onClose); 69 | } 70 | }, options.ttl, REPEAT_COUNT); 71 | } 72 | 73 | } 74 | }; 75 | 76 | } 77 | 78 | // Inject dependencies 79 | growlNotificationDirective.$inject = ['growlNotifications', '$animate', '$interval']; 80 | 81 | /** 82 | * Directive controller 83 | * 84 | * @param $element 85 | * @param $animate 86 | * @param $attrs 87 | * @param $scope 88 | */ 89 | function growlNotificationController($element, $animate, $attrs, $scope, $interval) { 90 | 91 | /** 92 | * Placeholder for timer promise 93 | */ 94 | this.timer = null; 95 | 96 | /** 97 | * Helper method to close notification manually 98 | */ 99 | this.remove = function () { 100 | 101 | // Remove the element 102 | $animate.leave($element); 103 | 104 | // Cancel scheduled automatic removal if there is one 105 | if (this.timer) { 106 | $interval.cancel(this.timer); 107 | 108 | // Run onClose handler if there is one 109 | if($attrs.onClose){ 110 | $scope.$eval($attrs.onClose); 111 | } 112 | } 113 | }; 114 | 115 | } 116 | 117 | // Inject dependencies 118 | growlNotificationController.$inject = ['$element', '$animate', '$attrs', '$scope', '$interval']; 119 | 120 | // Export 121 | angular 122 | .module('growlNotifications.directives') 123 | .directive('growlNotification', growlNotificationDirective); 124 | 125 | })(); 126 | -------------------------------------------------------------------------------- /src/growlNotifications/directives/growlNotifications.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | /** 4 | * Create directive definition object 5 | * 6 | * @param growlNotifications 7 | */ 8 | function growlNotificationsDirective(growlNotifications) { 9 | 10 | return { 11 | 12 | /** 13 | * Allow compilation via attributes as well so custom 14 | * markup can be used 15 | */ 16 | restrict: 'AE', 17 | 18 | /** 19 | * Post link function 20 | * 21 | * @param scope 22 | * @param iElem 23 | * @param iAttrs 24 | */ 25 | link: function (scope, iElem, iAttrs) { 26 | growlNotifications.element = iElem; 27 | } 28 | }; 29 | 30 | } 31 | 32 | // Inject dependencies 33 | growlNotificationsDirective.$inject = ['growlNotifications']; 34 | 35 | // Export 36 | angular 37 | .module('growlNotifications.directives') 38 | .directive('growlNotifications', growlNotificationsDirective); 39 | 40 | })(); -------------------------------------------------------------------------------- /src/growlNotifications/growlNotifications.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // Config 4 | angular.module('growlNotifications.config', []) 5 | .value('growlNotifications.config', { 6 | debug: true 7 | }); 8 | 9 | // Modules 10 | angular.module('growlNotifications.directives', []); 11 | angular.module('growlNotifications.filters', []); 12 | angular.module('growlNotifications.services', []); 13 | angular.module('growlNotifications', 14 | [ 15 | 'growlNotifications.config', 16 | 'growlNotifications.directives', 17 | 'growlNotifications.filters', 18 | 'growlNotifications.services' 19 | ]); 20 | 21 | })(); 22 | -------------------------------------------------------------------------------- /src/growlNotifications/services/growlNotifications.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | /** 4 | * Growl notifications provider 5 | */ 6 | function growlNotificationsProvider() { 7 | 8 | // Default options 9 | var options = { 10 | ttl: 5000 11 | }; 12 | 13 | /** 14 | * Provider method to change default options 15 | * 16 | * @param newOptions 17 | */ 18 | this.setOptions = function (newOptions) { 19 | angular.extend(options, newOptions); 20 | return this; 21 | }; 22 | 23 | /** 24 | * Provider convenience method to get or set default ttl 25 | * 26 | * @param ttl 27 | * @returns {*} 28 | */ 29 | this.ttl = function (ttl) { 30 | if (angular.isDefined(ttl)) { 31 | options.ttl = ttl; 32 | return this; 33 | } 34 | return options.ttl; 35 | }; 36 | 37 | /** 38 | * Factory method 39 | * 40 | * @param $timeout 41 | * @param $rootScope 42 | * @returns {GrowlNotifications} 43 | */ 44 | this.$get = function () { 45 | 46 | function GrowlNotifications() { 47 | 48 | this.options = options; 49 | this.element = null; 50 | 51 | } 52 | 53 | return new GrowlNotifications(); 54 | 55 | }; 56 | 57 | } 58 | 59 | // Export 60 | angular 61 | .module('growlNotifications.services') 62 | .provider('growlNotifications', growlNotificationsProvider); 63 | 64 | })(); 65 | -------------------------------------------------------------------------------- /test/unit/growlNotifications/directive/growlNotificationSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('growlNotification directive', function () { 4 | 5 | var growlNotifications, 6 | $compile, 7 | $rootScope, 8 | markup; 9 | 10 | beforeEach(module('growlNotifications')); 11 | 12 | beforeEach(inject(function (_growlNotifications_, _$compile_, _$rootScope_) { 13 | growlNotifications = _growlNotifications_; 14 | $compile = _$compile_; 15 | $rootScope = _$rootScope_; 16 | })); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /test/unit/growlNotifications/growlNotificationsSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('growlNotifications', function () { 4 | 5 | var module; 6 | var dependencies; 7 | dependencies = []; 8 | 9 | var hasModule = function (module) { 10 | return dependencies.indexOf(module) >= 0; 11 | }; 12 | 13 | beforeEach(function () { 14 | 15 | // Get module 16 | module = angular.module('growlNotifications'); 17 | dependencies = module.requires; 18 | }); 19 | 20 | it('should load config module', function () { 21 | expect(hasModule('growlNotifications.config')).toBeTruthy(); 22 | }); 23 | 24 | 25 | it('should load filters module', function () { 26 | expect(hasModule('growlNotifications.filters')).toBeTruthy(); 27 | }); 28 | 29 | 30 | it('should load directives module', function () { 31 | expect(hasModule('growlNotifications.directives')).toBeTruthy(); 32 | }); 33 | 34 | 35 | it('should load services module', function () { 36 | expect(hasModule('growlNotifications.services')).toBeTruthy(); 37 | }); 38 | 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /test/unit/growlNotifications/services/growlNotificationsSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('growlNotifications service', function () { 4 | 5 | var growlNotifications; 6 | 7 | beforeEach(module('growlNotifications')); 8 | 9 | beforeEach(inject(function (_growlNotifications_) { 10 | growlNotifications = _growlNotifications_; 11 | })); 12 | 13 | it('should exist', function () { 14 | expect(growlNotifications).toBeDefined(); 15 | }); 16 | 17 | }); 18 | --------------------------------------------------------------------------------