├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── bootstrap-notify.js
├── bootstrap-notify.min.js
├── bower.json
├── composer.json
├── jshintrc.json
├── package.js
├── package.json
├── test_meteor.js
└── typings
└── bootstrap-notify
└── notify.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | // Project configuration.
3 | grunt.initConfig({
4 | pkg: grunt.file.readJSON('package.json'),
5 | uglify: {
6 | options: {
7 | compress: {
8 | drop_console: true
9 | },
10 | preserveComments: 'some'
11 | },
12 | default: {
13 | files: {
14 | 'bootstrap-notify.min.js': ['bootstrap-notify.js']
15 | }
16 | }
17 | },
18 | jshint: {
19 | options: {
20 | jshintrc: 'jshintrc.json'
21 | },
22 | default: {
23 | src: 'bootstrap-notify.js'
24 | }
25 | },
26 | exec: {
27 | 'meteor-test': 'node_modules/.bin/spacejam test-packages ./'
28 | }
29 | });
30 |
31 | grunt.loadNpmTasks('grunt-contrib-uglify');
32 | grunt.loadNpmTasks('grunt-contrib-jshint');
33 | grunt.loadNpmTasks('grunt-exec');
34 |
35 | grunt.registerTask('test', ['jshint', 'exec:meteor-test']);
36 | grunt.registerTask('default', ['uglify']);
37 | };
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Robert McIntosh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap Notify
2 | This is a simple plugin that turns standard Bootstrap alerts into "Growl-like" notifications.
3 |
4 | ## Manual Download - Stable Release
5 | If toy would like to download the latest stable release please follow the link below
6 | - [Stable Release](https://github.com/mouse0270/bootstrap-notify/releases/latest)
7 |
8 | Please keep in mind that the master branch may contain bugs or broken code. Please use the link above if you are not able to debug and correct issues in the master branch. Thank you.
9 |
10 | ## Bower Officially Supported
11 | I would like to thank [Błażej Krysiak](https://github.com/IjinPL) for doing this!
12 | ```
13 | bower install remarkable-bootstrap-notify
14 | ```
15 |
16 | ## Meteor Officially Supported
17 | Meteor integration by [zimme](https://github.com/zimme).
18 |
19 | ```sh
20 | meteor add mouse0270:bootstrap-notify
21 | ```
22 |
23 | ## Changelog
24 | #### Version 3.1.5 provided by [chrismbarr](https://github.com/chrismbarr) - *Testing*
25 | - Cleaned Up Code
26 | - Fixed Spelling
27 | - Added Option to prevent Duplicate Notifications
28 | - TypeScript Definitions File
29 |
30 | ##### Version 3.1.3 - *Stable Release*
31 | - Added Meteor Support
32 | - Fixed issue with Glyphicons Pro
33 | - Updating version pattern.
34 | ```
35 | x.y.z
36 | x = Main version of the plugin
37 | y = New features were added to the plugin
38 | z = Fixes/patches to existing features of the plugin
39 | ```
40 |
41 | ##### [Version 3.0.2](http://bootstrap-notify.remabledesigns.com/3.0.2/)
42 | - Fixed update for backwards compatibility
43 |
44 | ##### [Version 3.0.1](http://bootstrap-notify.remabledesigns.com/3.0.1/)
45 | - Add the ability to update multiple values in one call
46 | - Turn off Progress bar
47 | - Set Progress bar value / Progress bar not shown by default
48 | ``` javascript
49 | //Update
50 | var notify = $.notify('Saving Do not close this page...', { allow_dismiss: false });
51 | notify.update({ type: 'success', 'Success Your page has been saved!' });
52 |
53 | // Turn of Progress bar on
54 | $.notify('I have a progress bar', { showProgressbar: true });
55 |
56 | // Update Progress bar
57 | var notify = $.notify('Saving Do not close this page...', { allow_dismiss: false });
58 | notify.update({ type: 'warning', 'Oops Something happened. Correcting Now', progress: 20 });
59 | ```
60 |
61 | ##### [Version 3.0.0](http://bootstrap-notify.remabledesigns.com/3.0.0/)
62 | - New template structure
63 | - Better event handling for onShow, onShown, onClose, onClosed
64 | - updating notification content will reposition growls below it
65 | - Fixed updating icon images
66 | - Fixed IE Issues with Growl URL not being able to be clicked on
67 | - Added the ability to show progress bars
68 | - Added the ability to pass position in the settings
69 | - Added *_newest_on_top_* option that allows new growls to push down old growls
70 | - Added Transition CSS to plugin
71 | ```css
72 | transition: all 0.5 ease-in-out;
73 | ```
74 | - Remember to read to documentation. I use custom css style's for the progress bar that you can find there. This was left out of the plugin so you could choose to use the default progressbar styles provided for bootstrap or write your own.
75 |
76 | ##### [Version 2.0.1](http://bootstrap-growl.remabledesigns.com/2.0.1/)
77 | - Added the ability to set an X and Y value within the offset option
78 | - Added callback options onShow, onShown, onHide and onHidden
79 | - Added a close all method to close all open growls
80 |
81 | ##### [Version 2.0.0a3](http://bootstrap-growl.remabledesigns.com/2.0.0a3/)
82 | - Fixed issue with growl not closing if there was no CSS animations
83 |
84 | ##### [Version 2.0.0a2](http://bootstrap-growl.remabledesigns.com/2.0.0a2/) (with IE8 Support)
85 | - Changed animate.in to animate.enter for IE8 compatibility
86 | - Changed animate.out to animate.exit for IE8 compatibility
87 | - Modified .is(':hover') for IE8 compatibility
88 |
89 | ##### [Version 2.0.0a1](http://bootstrap-growl.remabledesigns.com/2.0.0a1/)
90 | - Better Minification
91 |
92 | ##### [Version 2.0.0a](http://bootstrap-growl.remabledesigns.com/2.0.0a1/)
93 | - Major rewright of the plugin file.
94 | - Added the ability to pass the growl a link making it clickable.
95 | - Added the ability to control the growl animations in and out using css.
96 | - Added the ability to set growl settings globally.
97 | - Removed jQuery fadeIn (use css to control growl animations)
98 |
99 | ##### [Version 1.0.6](http://bootstrap-growl.remabledesigns.com/1.0.6/)
100 | - Added onGrowlShow and onGrowlShown callback functionality.
101 |
102 | ##### Version 1.0.5
103 | - Better positioning when using CSS animations after growl closes.
104 |
105 | ##### Version 1.0.4
106 | - Updated $.growl() to return a wrapper object with a small API to let you control individual notifications after they have been created.
107 | - Added onGrowlClose and onGrowlClosed callback functionality.
108 |
109 | ##### Version 1.0.3
110 | - Made jQuery $.extend() Recursive so when you change just one option under position or template the script wont fail
111 |
112 | ##### Version 1.0.2
113 | - Fixed an issue where $.growl("message") would thrown an exception | Provided by [DannyJo](https://github.com/DannyJo/bootstrap-growl)
114 |
115 | ##### Version 1.0.0
116 | - Initial Release
117 |
118 | ## Demo and Documentation
119 | - [Demo](http://bootstrap-growl.remabledesigns.com/)
120 | - [Documentation](http://bootstrap-notify.remabledesigns.com/#documentation)
121 |
122 | NOTE: Some users have reported an issue where the demo/documentation links repsond with only `pageok` in the body. If that occurs for you, try emptying your browser cache or an alternate browser.
123 |
124 | ## Dependencies
125 | - [jQuery v1.10.2](http://jquery.com/)
126 | - [Bootstrap v2.0.0 - 3.2.0](http://getbootstrap.com/)
127 |
128 | ## Copyright and License
129 | The MIT License (MIT)
130 | Copyright (c) 2015 Robert McIntosh
131 |
132 | Permission is hereby granted, free of charge, to any person obtaining a copy of
133 | this software and associated documentation files (the "Software"), to deal in
134 | the Software without restriction, including without limitation the rights to
135 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
136 | the Software, and to permit persons to whom the Software is furnished to do so,
137 | subject to the following conditions:
138 |
139 | The above copyright notice and this permission notice shall be included in all
140 | copies or substantial portions of the Software.
141 |
142 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
143 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
144 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
145 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
146 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
147 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
148 |
--------------------------------------------------------------------------------
/bootstrap-notify.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: Bootstrap Notify = v3.1.5
3 | * Description: Turns standard Bootstrap alerts into "Growl-like" notifications.
4 | * Author: Mouse0270 aka Robert McIntosh
5 | * License: MIT License
6 | * Website: https://github.com/mouse0270/bootstrap-growl
7 | */
8 |
9 | /* global define:false, require: false, jQuery:false */
10 |
11 | (function (factory) {
12 | if (typeof define === 'function' && define.amd) {
13 | // AMD. Register as an anonymous module.
14 | define(['jquery'], factory);
15 | } else if (typeof exports === 'object') {
16 | // Node/CommonJS
17 | factory(require('jquery'));
18 | } else {
19 | // Browser globals
20 | factory(jQuery);
21 | }
22 | }(function ($) {
23 | // Create the defaults once
24 | var defaults = {
25 | element: 'body',
26 | position: null,
27 | type: "info",
28 | allow_dismiss: true,
29 | allow_duplicates: true,
30 | newest_on_top: false,
31 | showProgressbar: false,
32 | placement: {
33 | from: "top",
34 | align: "right"
35 | },
36 | offset: 20,
37 | spacing: 10,
38 | z_index: 1031,
39 | delay: 5000,
40 | timer: 1000,
41 | url_target: '_blank',
42 | mouse_over: null,
43 | animate: {
44 | enter: 'animated fadeInDown',
45 | exit: 'animated fadeOutUp'
46 | },
47 | onShow: null,
48 | onShown: null,
49 | onClose: null,
50 | onClosed: null,
51 | onClick: null,
52 | icon_type: 'class',
53 | template: '
'
54 | };
55 |
56 | String.format = function () {
57 | var args = arguments;
58 | var str = arguments[0];
59 | return str.replace(/(\{\{\d\}\}|\{\d\})/g, function (str) {
60 | if (str.substring(0, 2) === "{{") return str;
61 | var num = parseInt(str.match(/\d/)[0]);
62 | return args[num + 1];
63 | });
64 | };
65 |
66 | function isDuplicateNotification(notification) {
67 | var isDupe = false;
68 |
69 | $('[data-notify="container"]').each(function (i, el) {
70 | var $el = $(el);
71 | var title = $el.find('[data-notify="title"]').html().trim();
72 | var message = $el.find('[data-notify="message"]').html().trim();
73 |
74 | // The input string might be different than the actual parsed HTML string!
75 | // (
vs
for example)
76 | // So we have to force-parse this as HTML here!
77 | var isSameTitle = title === $("" + notification.settings.content.title + "
").html().trim();
78 | var isSameMsg = message === $("" + notification.settings.content.message + "
").html().trim();
79 | var isSameType = $el.hasClass('alert-' + notification.settings.type);
80 |
81 | if (isSameTitle && isSameMsg && isSameType) {
82 | //we found the dupe. Set the var and stop checking.
83 | isDupe = true;
84 | }
85 | return !isDupe;
86 | });
87 |
88 | return isDupe;
89 | }
90 |
91 | function Notify(element, content, options) {
92 | // Setup Content of Notify
93 | var contentObj = {
94 | content: {
95 | message: typeof content === 'object' ? content.message : content,
96 | title: content.title ? content.title : '',
97 | icon: content.icon ? content.icon : '',
98 | url: content.url ? content.url : '#',
99 | target: content.target ? content.target : '-'
100 | }
101 | };
102 |
103 | options = $.extend(true, {}, contentObj, options);
104 | this.settings = $.extend(true, {}, defaults, options);
105 | this._defaults = defaults;
106 | if (this.settings.content.target === "-") {
107 | this.settings.content.target = this.settings.url_target;
108 | }
109 | this.animations = {
110 | start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart',
111 | end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend'
112 | };
113 |
114 | if (typeof this.settings.offset === 'number') {
115 | this.settings.offset = {
116 | x: this.settings.offset,
117 | y: this.settings.offset
118 | };
119 | }
120 |
121 | //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing
122 | if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) {
123 | this.init();
124 | }
125 | }
126 |
127 | $.extend(Notify.prototype, {
128 | init: function () {
129 | var self = this;
130 |
131 | this.buildNotify();
132 | if (this.settings.content.icon) {
133 | this.setIcon();
134 | }
135 | if (this.settings.content.url != "#") {
136 | this.styleURL();
137 | }
138 | this.styleDismiss();
139 | this.placement();
140 | this.bind();
141 |
142 | this.notify = {
143 | $ele: this.$ele,
144 | update: function (command, update) {
145 | var commands = {};
146 | if (typeof command === "string") {
147 | commands[command] = update;
148 | } else {
149 | commands = command;
150 | }
151 | for (var cmd in commands) {
152 | switch (cmd) {
153 | case "type":
154 | this.$ele.removeClass('alert-' + self.settings.type);
155 | this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type);
156 | self.settings.type = commands[cmd];
157 | this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]);
158 | break;
159 | case "icon":
160 | var $icon = this.$ele.find('[data-notify="icon"]');
161 | if (self.settings.icon_type.toLowerCase() === 'class') {
162 | $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]);
163 | } else {
164 | if (!$icon.is('img')) {
165 | $icon.find('img');
166 | }
167 | $icon.attr('src', commands[cmd]);
168 | }
169 | self.settings.content.icon = commands[command];
170 | break;
171 | case "progress":
172 | var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100));
173 | this.$ele.data('notify-delay', newDelay);
174 | this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%');
175 | break;
176 | case "url":
177 | this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]);
178 | break;
179 | case "target":
180 | this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]);
181 | break;
182 | default:
183 | this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]);
184 | }
185 | }
186 | var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y);
187 | self.reposition(posX);
188 | },
189 | close: function () {
190 | self.close();
191 | }
192 | };
193 |
194 | },
195 | buildNotify: function () {
196 | var content = this.settings.content;
197 | this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target));
198 | this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align);
199 | if (!this.settings.allow_dismiss) {
200 | this.$ele.find('[data-notify="dismiss"]').css('display', 'none');
201 | }
202 | if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) {
203 | this.$ele.find('[data-notify="progressbar"]').remove();
204 | }
205 | },
206 | setIcon: function () {
207 | if (this.settings.icon_type.toLowerCase() === 'class') {
208 | this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon);
209 | } else {
210 | if (this.$ele.find('[data-notify="icon"]').is('img')) {
211 | this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon);
212 | } else {
213 | this.$ele.find('[data-notify="icon"]').append('
');
214 | }
215 | }
216 | },
217 | styleDismiss: function () {
218 | this.$ele.find('[data-notify="dismiss"]').css({
219 | position: 'absolute',
220 | right: '10px',
221 | top: '5px',
222 | zIndex: this.settings.z_index + 2
223 | });
224 | },
225 | styleURL: function () {
226 | this.$ele.find('[data-notify="url"]').css({
227 | backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)',
228 | height: '100%',
229 | left: 0,
230 | position: 'absolute',
231 | top: 0,
232 | width: '100%',
233 | zIndex: this.settings.z_index + 1
234 | });
235 | },
236 | placement: function () {
237 | var self = this,
238 | offsetAmt = this.settings.offset.y,
239 | css = {
240 | display: 'inline-block',
241 | margin: '0px auto',
242 | position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'),
243 | transition: 'all .5s ease-in-out',
244 | zIndex: this.settings.z_index
245 | },
246 | hasAnimation = false,
247 | settings = this.settings;
248 |
249 | $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () {
250 | offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing));
251 | });
252 | if (this.settings.newest_on_top === true) {
253 | offsetAmt = this.settings.offset.y;
254 | }
255 | css[this.settings.placement.from] = offsetAmt + 'px';
256 |
257 | switch (this.settings.placement.align) {
258 | case "left":
259 | case "right":
260 | css[this.settings.placement.align] = this.settings.offset.x + 'px';
261 | break;
262 | case "center":
263 | css.left = 0;
264 | css.right = 0;
265 | break;
266 | }
267 | this.$ele.css(css).addClass(this.settings.animate.enter);
268 | $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function (index, prefix) {
269 | self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1;
270 | });
271 |
272 | $(this.settings.element).append(this.$ele);
273 |
274 | if (this.settings.newest_on_top === true) {
275 | offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight();
276 | this.reposition(offsetAmt);
277 | }
278 |
279 | if ($.isFunction(self.settings.onShow)) {
280 | self.settings.onShow.call(this.$ele);
281 | }
282 |
283 | this.$ele.one(this.animations.start, function () {
284 | hasAnimation = true;
285 | }).one(this.animations.end, function () {
286 | self.$ele.removeClass(self.settings.animate.enter);
287 | if ($.isFunction(self.settings.onShown)) {
288 | self.settings.onShown.call(this);
289 | }
290 | });
291 |
292 | setTimeout(function () {
293 | if (!hasAnimation) {
294 | if ($.isFunction(self.settings.onShown)) {
295 | self.settings.onShown.call(this);
296 | }
297 | }
298 | }, 600);
299 | },
300 | bind: function () {
301 | var self = this;
302 |
303 | this.$ele.find('[data-notify="dismiss"]').on('click', function () {
304 | self.close();
305 | });
306 |
307 | if ($.isFunction(self.settings.onClick)) {
308 | this.$ele.on('click', function (event) {
309 | if (event.target != self.$ele.find('[data-notify="dismiss"]')[0]) {
310 | self.settings.onClick.call(this, event);
311 | }
312 | });
313 | }
314 |
315 | this.$ele.mouseover(function () {
316 | $(this).data('data-hover', "true");
317 | }).mouseout(function () {
318 | $(this).data('data-hover', "false");
319 | });
320 | this.$ele.data('data-hover', "false");
321 |
322 | if (this.settings.delay > 0) {
323 | self.$ele.data('notify-delay', self.settings.delay);
324 | var timer = setInterval(function () {
325 | var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer;
326 | if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") {
327 | var percent = ((self.settings.delay - delay) / self.settings.delay) * 100;
328 | self.$ele.data('notify-delay', delay);
329 | self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%');
330 | }
331 | if (delay <= -(self.settings.timer)) {
332 | clearInterval(timer);
333 | self.close();
334 | }
335 | }, self.settings.timer);
336 | }
337 | },
338 | close: function () {
339 | var self = this,
340 | posX = parseInt(this.$ele.css(this.settings.placement.from)),
341 | hasAnimation = false;
342 |
343 | this.$ele.attr('data-closing', 'true').addClass(this.settings.animate.exit);
344 | self.reposition(posX);
345 |
346 | if ($.isFunction(self.settings.onClose)) {
347 | self.settings.onClose.call(this.$ele);
348 | }
349 |
350 | this.$ele.one(this.animations.start, function () {
351 | hasAnimation = true;
352 | }).one(this.animations.end, function () {
353 | $(this).remove();
354 | if ($.isFunction(self.settings.onClosed)) {
355 | self.settings.onClosed.call(this);
356 | }
357 | });
358 |
359 | setTimeout(function () {
360 | if (!hasAnimation) {
361 | self.$ele.remove();
362 | if ($.isFunction(self.settings.onClosed)) {
363 | self.settings.onClosed.call(this);
364 | }
365 | }
366 | }, 600);
367 | },
368 | reposition: function (posX) {
369 | var self = this,
370 | notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])',
371 | $elements = this.$ele.nextAll(notifies);
372 | if (this.settings.newest_on_top === true) {
373 | $elements = this.$ele.prevAll(notifies);
374 | }
375 | $elements.each(function () {
376 | $(this).css(self.settings.placement.from, posX);
377 | posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight();
378 | });
379 | }
380 | });
381 |
382 | $.notify = function (content, options) {
383 | var plugin = new Notify(this, content, options);
384 | return plugin.notify;
385 | };
386 | $.notifyDefaults = function (options) {
387 | defaults = $.extend(true, {}, defaults, options);
388 | return defaults;
389 | };
390 |
391 | $.notifyClose = function (selector) {
392 |
393 | if (typeof selector === "undefined" || selector === "all") {
394 | $('[data-notify]').find('[data-notify="dismiss"]').trigger('click');
395 | }else if(selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger'){
396 | $('.alert-' + selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
397 | } else if(selector){
398 | $(selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
399 | }
400 | else {
401 | $('[data-notify-position="' + selector + '"]').find('[data-notify="dismiss"]').trigger('click');
402 | }
403 | };
404 |
405 | $.notifyCloseExcept = function (selector) {
406 |
407 | if(selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger'){
408 | $('[data-notify]').not('.alert-' + selector).find('[data-notify="dismiss"]').trigger('click');
409 | } else{
410 | $('[data-notify]').not(selector).find('[data-notify="dismiss"]').trigger('click');
411 | }
412 | };
413 |
414 |
415 | }));
416 |
417 |
418 |
--------------------------------------------------------------------------------
/bootstrap-notify.min.js:
--------------------------------------------------------------------------------
1 | !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){function s(s){var e=!1;return t('[data-notify="container"]').each(function(i,n){var a=t(n),o=a.find('[data-notify="title"]').text().trim(),r=a.find('[data-notify="message"]').html().trim(),l=o===t(""+s.settings.content.title+"
").html().trim(),d=r===t(""+s.settings.content.message+"
").html().trim(),g=a.hasClass("alert-"+s.settings.type);return l&&d&&g&&(e=!0),!e}),e}function e(e,n,a){var o={content:{message:"object"==typeof n?n.message:n,title:n.title?n.title:"",icon:n.icon?n.icon:"",url:n.url?n.url:"#",target:n.target?n.target:"-"}};a=t.extend(!0,{},o,a),this.settings=t.extend(!0,{},i,a),this._defaults=i,"-"===this.settings.content.target&&(this.settings.content.target=this.settings.url_target),this.animations={start:"webkitAnimationStart oanimationstart MSAnimationStart animationstart",end:"webkitAnimationEnd oanimationend MSAnimationEnd animationend"},"number"==typeof this.settings.offset&&(this.settings.offset={x:this.settings.offset,y:this.settings.offset}),(this.settings.allow_duplicates||!this.settings.allow_duplicates&&!s(this))&&this.init()}var i={element:"body",position:null,type:"info",allow_dismiss:!0,allow_duplicates:!0,newest_on_top:!1,showProgressbar:!1,placement:{from:"top",align:"right"},offset:20,spacing:10,z_index:1031,delay:5e3,timer:1e3,url_target:"_blank",mouse_over:null,animate:{enter:"animated fadeInDown",exit:"animated fadeOutUp"},onShow:null,onShown:null,onClose:null,onClosed:null,icon_type:"class",template:''};String.format=function(){for(var t=arguments[0],s=1;s .progress-bar').removeClass("progress-bar-"+t.settings.type),t.settings.type=i[n],this.$ele.addClass("alert-"+i[n]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-"+i[n]);break;case"icon":var a=this.$ele.find('[data-notify="icon"]');"class"===t.settings.icon_type.toLowerCase()?a.removeClass(t.settings.content.icon).addClass(i[n]):(a.is("img")||a.find("img"),a.attr("src",i[n]));break;case"progress":var o=t.settings.delay-t.settings.delay*(i[n]/100);this.$ele.data("notify-delay",o),this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i[n]).css("width",i[n]+"%");break;case"url":this.$ele.find('[data-notify="url"]').attr("href",i[n]);break;case"target":this.$ele.find('[data-notify="url"]').attr("target",i[n]);break;default:this.$ele.find('[data-notify="'+n+'"]').html(i[n])}var r=this.$ele.outerHeight()+parseInt(t.settings.spacing)+parseInt(t.settings.offset.y);t.reposition(r)},close:function(){t.close()}}},buildNotify:function(){var s=this.settings.content;this.$ele=t(String.format(this.settings.template,this.settings.type,s.title,s.message,s.url,s.target)),this.$ele.attr("data-notify-position",this.settings.placement.from+"-"+this.settings.placement.align),this.settings.allow_dismiss||this.$ele.find('[data-notify="dismiss"]').css("display","none"),(this.settings.delay<=0&&!this.settings.showProgressbar||!this.settings.showProgressbar)&&this.$ele.find('[data-notify="progressbar"]').remove()},setIcon:function(){"class"===this.settings.icon_type.toLowerCase()?this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon):this.$ele.find('[data-notify="icon"]').is("img")?this.$ele.find('[data-notify="icon"]').attr("src",this.settings.content.icon):this.$ele.find('[data-notify="icon"]').append('
')},styleDismiss:function(){this.$ele.find('[data-notify="dismiss"]').css({position:"absolute",right:"10px",top:"5px",zIndex:this.settings.z_index+2})},styleURL:function(){this.$ele.find('[data-notify="url"]').css({backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)",height:"100%",left:0,position:"absolute",top:0,width:"100%",zIndex:this.settings.z_index+1})},placement:function(){var s=this,e=this.settings.offset.y,i={display:"inline-block",margin:"0px auto",position:this.settings.position?this.settings.position:"body"===this.settings.element?"fixed":"absolute",transition:"all .5s ease-in-out",zIndex:this.settings.z_index},n=!1,a=this.settings;switch(t('[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])').each(function(){e=Math.max(e,parseInt(t(this).css(a.placement.from))+parseInt(t(this).outerHeight())+parseInt(a.spacing))}),this.settings.newest_on_top===!0&&(e=this.settings.offset.y),i[this.settings.placement.from]=e+"px",this.settings.placement.align){case"left":case"right":i[this.settings.placement.align]=this.settings.offset.x+"px";break;case"center":i.left=0,i.right=0}this.$ele.css(i).addClass(this.settings.animate.enter),t.each(Array("webkit-","moz-","o-","ms-",""),function(t,e){s.$ele[0].style[e+"AnimationIterationCount"]=1}),t(this.settings.element).append(this.$ele),this.settings.newest_on_top===!0&&(e=parseInt(e)+parseInt(this.settings.spacing)+this.$ele.outerHeight(),this.reposition(e)),t.isFunction(s.settings.onShow)&&s.settings.onShow.call(this.$ele),this.$ele.one(this.animations.start,function(){n=!0}).one(this.animations.end,function(){s.$ele.removeClass(s.settings.animate.enter),t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)}),setTimeout(function(){n||t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)},600)},bind:function(){var s=this;if(this.$ele.find('[data-notify="dismiss"]').on("click",function(){s.close()}),this.$ele.mouseover(function(){t(this).data("data-hover","true")}).mouseout(function(){t(this).data("data-hover","false")}),this.$ele.data("data-hover","false"),this.settings.delay>0){s.$ele.data("notify-delay",s.settings.delay);var e=setInterval(function(){var t=parseInt(s.$ele.data("notify-delay"))-s.settings.timer;if("false"===s.$ele.data("data-hover")&&"pause"===s.settings.mouse_over||"pause"!=s.settings.mouse_over){var i=(s.settings.delay-t)/s.settings.delay*100;s.$ele.data("notify-delay",t),s.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i).css("width",i+"%")}t<=-s.settings.timer&&(clearInterval(e),s.close())},s.settings.timer)}},close:function(){var s=this,e=parseInt(this.$ele.css(this.settings.placement.from)),i=!1;this.$ele.attr("data-closing","true").addClass(this.settings.animate.exit),s.reposition(e),t.isFunction(s.settings.onClose)&&s.settings.onClose.call(this.$ele),this.$ele.one(this.animations.start,function(){i=!0}).one(this.animations.end,function(){t(this).remove(),t.isFunction(s.settings.onClosed)&&s.settings.onClosed.call(this)}),setTimeout(function(){i||(s.$ele.remove(),s.settings.onClosed&&s.settings.onClosed(s.$ele))},600)},reposition:function(s){var e=this,i='[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])',n=this.$ele.nextAll(i);this.settings.newest_on_top===!0&&(n=this.$ele.prevAll(i)),n.each(function(){t(this).css(e.settings.placement.from,s),s=parseInt(s)+parseInt(e.settings.spacing)+t(this).outerHeight()})}}),t.notify=function(t,s){var i=new e(this,t,s);return i.notify},t.notifyDefaults=function(s){return i=t.extend(!0,{},i,s)},t.notifyClose=function(s){"warning"===s&&(s="danger"),"undefined"==typeof s||"all"===s?t("[data-notify]").find('[data-notify="dismiss"]').trigger("click"):"success"===s||"info"===s||"warning"===s||"danger"===s?t(".alert-"+s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):s?t(s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):t('[data-notify-position="'+s+'"]').find('[data-notify="dismiss"]').trigger("click")},t.notifyCloseExcept=function(s){"warning"===s&&(s="danger"),"success"===s||"info"===s||"warning"===s||"danger"===s?t("[data-notify]").not(".alert-"+s).find('[data-notify="dismiss"]').trigger("click"):t("[data-notify]").not(s).find('[data-notify="dismiss"]').trigger("click")}});
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "remarkable-bootstrap-notify",
3 | "main": "bootstrap-notify.js",
4 | "version": "3.1.7",
5 | "homepage": "http://bootstrap-notify.remabledesigns.com/",
6 | "authors": [
7 | "mouse0270 "
8 | ],
9 | "description": "This is a simple plugin that turns standard Bootstrap alerts into \"Growl-like\" notifications.",
10 | "keywords": [
11 | "remarkable",
12 | "bootstrap",
13 | "jquery",
14 | "notify",
15 | "notification",
16 | "notifications",
17 | "growl",
18 | "message",
19 | "notice"
20 | ],
21 | "dependencies": {
22 | "jquery": ">=1.10.2",
23 | "bootstrap": ">=2.0.0"
24 | },
25 | "license": "MIT",
26 | "ignore": []
27 | }
28 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mouse0270/bootstrap-notify",
3 | "version": "3.1.5",
4 | "type": "library",
5 | "description": "This is a simple pluging that turns standard Bootstrap alerts into \"Growl-like\" notifications.",
6 | "keywords": [
7 | "bootstrap",
8 | "jquery",
9 | "notify",
10 | "notification",
11 | "notifications",
12 | "growl",
13 | "message",
14 | "notice"
15 | ],
16 | "authors": [
17 | {
18 | "name": "mouse0270",
19 | "email": "rmcintosh@remabledesigns.com",
20 | "homepage": "http://bootstrap-notify.remabledesigns.com/",
21 | "role": "Developer"
22 | }
23 | ],
24 | "homepage": "http://bootstrap-notify.remabledesigns.com/",
25 | "license": "MIT",
26 | "autoload": {}
27 | }
--------------------------------------------------------------------------------
/jshintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "bitwise": true,
3 | "curly": true,
4 | "eqeqeq": true,
5 | "forin": true,
6 | "freeze": true,
7 | "immed": true,
8 | "latedef": true,
9 | "noarg": true,
10 | "noempty": true,
11 | "nonbsp": true,
12 | "nonew": true,
13 | "undef": true,
14 | "unused": true,
15 | "strict": false,
16 | "trailing": true,
17 | "maxparams": 5,
18 | "sub": true,
19 | "devel": true,
20 | "browser": true,
21 |
22 | "globals": {
23 | "jQuery": false
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | git: 'git://github.com/mouse0270/bootstrap-notify.git',
3 | name: 'mouse0270:bootstrap-notify',
4 | summary: 'Turns standard Bootstrap alerts into "Growl-like" notifications',
5 | version: '3.1.5',
6 | });
7 |
8 | Package.onUse(function (api) {
9 | api.versionsFrom('1.0');
10 | api.use('jquery', 'client');
11 | api.addFiles('bootstrap-notify.js', 'client');
12 | });
13 |
14 | Package.onTest(function (api) {
15 | api.use('mouse0270:bootstrap-notify', 'client');
16 | api.use('tinytest', 'client');
17 |
18 | api.addFiles('test_meteor.js', 'client');
19 | });
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap-notify",
3 | "version": "3.1.7",
4 | "description": "This is a simple plugin that turns standard Bootstrap alerts into \"Growl-like\" notifications.",
5 | "repository": {
6 | "type": "git",
7 | "url": "git://github.com/mouse0270/bootstrap-notify.git"
8 | },
9 | "keywords": [
10 | "bootstrap",
11 | "jquery",
12 | "notify",
13 | "notification",
14 | "notifications",
15 | "growl",
16 | "message",
17 | "notice"
18 | ],
19 | "author": "mouse0270 ",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/mouse0270/bootstrap-notify/issues"
23 | },
24 | "homepage": "http://bootstrap-notify.remabledesigns.com/",
25 | "main": "bootstrap-notify.js",
26 | "files": [
27 | "bootstrap-notify.js",
28 | "bootstrap-notify.min.js"
29 | ],
30 | "dependencies": {},
31 | "devDependencies": {
32 | "grunt": "^0.4.5",
33 | "grunt-cli": "^0.1.13",
34 | "grunt-contrib-jshint": "^0.10.0",
35 | "grunt-contrib-uglify": "^0.4.0",
36 | "grunt-exec": "^0.4.6",
37 | "spacejam": "^1.1.4"
38 | },
39 | "scripts": {
40 | "test": "grunt test"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test_meteor.js:
--------------------------------------------------------------------------------
1 | Tinytest.add('Instantiation', function(test) {
2 | test.notEqual($.notify, undefined);
3 | });
4 |
--------------------------------------------------------------------------------
/typings/bootstrap-notify/notify.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /* tslint:disable: interface-name no-any */
4 |
5 | interface JQueryStatic {
6 | /* tslint:enable: interface-name */
7 | notify(message: string): INotifyReturn;
8 | notify(opts: INotifyOptions, settings?: INotifySettings): INotifyReturn;
9 | notifyDefaults(settings: INotifySettings): void;
10 | notifyClose(): void;
11 | notifyClose(command: string): void;
12 | }
13 |
14 | interface INotifyOptions {
15 | message: string;
16 | title?: string;
17 | icon?: string;
18 | url?: string;
19 | target?: string;
20 | }
21 |
22 | interface INotifySettings {
23 | element?: string;
24 | position?: string;
25 | type?: string;
26 | allow_dismiss?: boolean;
27 | allow_duplicates?: boolean;
28 | newest_on_top?: boolean;
29 | showProgressbar?: boolean;
30 | placement?: {
31 | from?: string;
32 | align?: string;
33 | };
34 | offset?: number;
35 | spacing?: number;
36 | z_index?: number;
37 | delay?: number;
38 | timer?: number;
39 | url_target?: string;
40 | mouse_over?: Function;
41 | animate?: {
42 | enter?: string;
43 | exit?: string;
44 | };
45 | onShow?: () => void;
46 | onShown?: () => void;
47 | onClose?: () => void;
48 | onClosed?: () => void;
49 | icon_type?: string;
50 | template?: string;
51 | }
52 |
53 | interface UpdateCommands {
54 | type?: string;
55 | progress?: number;
56 | message?: string;
57 | icon?: string;
58 | }
59 |
60 | interface NotifyReturn {
61 | $ele: JQueryStatic;
62 | close(): void;
63 | update(commands: UpdateCommands|Record): void;
64 | update(command: string, update: any): void;
65 | }
66 |
--------------------------------------------------------------------------------