|
| 1 | +/* |
| 2 | +* Project: Bootstrap Growl - v2.0.1 |
| 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 | +;(function ( $, window, document, undefined ) { |
| 9 | + // Create the defaults once |
| 10 | + var pluginName = "growl", |
| 11 | + dataKey = "plugin_" + pluginName, |
| 12 | + defaults = { |
| 13 | + element: 'body', |
| 14 | + type: "info", |
| 15 | + allow_dismiss: true, |
| 16 | + placement: { |
| 17 | + from: "top", |
| 18 | + align: "right" |
| 19 | + }, |
| 20 | + offset: 20, |
| 21 | + spacing: 10, |
| 22 | + z_index: 1031, |
| 23 | + delay: 5000, |
| 24 | + timer: 1000, |
| 25 | + url_target: '_blank', |
| 26 | + mouse_over: false, |
| 27 | + animate: { |
| 28 | + enter: 'animated fadeInDown', |
| 29 | + exit: 'animated fadeOutUp' |
| 30 | + }, |
| 31 | + onShow: null, |
| 32 | + onShown: null, |
| 33 | + onHide: null, |
| 34 | + onHidden: null, |
| 35 | + icon_type: 'class', |
| 36 | + template: '<div data-growl="container" class="alert" role="alert"><button type="button" aria-hidden="true" class="close" data-growl="dismiss">×</button><span data-growl="icon"></span><span data-growl="title"></span><span data-growl="message"></span><a href="#" data-growl="url"></a></div>' |
| 37 | + }; |
| 38 | + |
| 39 | + // The actual plugin constructor |
| 40 | + var setDefaults = function(element, options) { |
| 41 | + defaults = $.extend(true, {}, defaults, options); |
| 42 | + }, |
| 43 | + closeAll = function(options) { |
| 44 | + if (!options) { |
| 45 | + $('[data-growl="container"]').find('[data-growl="dismiss"]').trigger('click'); |
| 46 | + }else{ |
| 47 | + $('[data-growl="container"][data-growl-position="'+options+'"]').find('[data-growl="dismiss"]').trigger('click'); |
| 48 | + } |
| 49 | + }, |
| 50 | + Plugin = function (element, content, options) { |
| 51 | + var content = { |
| 52 | + content: { |
| 53 | + message: typeof content == 'object' ? content.message : content, |
| 54 | + title: content.title ? content.title : null, |
| 55 | + icon: content.icon ? content.icon : null, |
| 56 | + url: content.url ? content.url : null |
| 57 | + } |
| 58 | + }; |
| 59 | + |
| 60 | + options = $.extend(true, {}, content, options); |
| 61 | + this.settings = $.extend(true, {}, defaults, options); |
| 62 | + plugin = this; |
| 63 | + init(options, this.settings, plugin); |
| 64 | + this.$template = $template; |
| 65 | + }, |
| 66 | + init = function (options, settings, plugin) { |
| 67 | + |
| 68 | + var base = { |
| 69 | + settings: settings, |
| 70 | + element: settings.element, |
| 71 | + template: settings.template |
| 72 | + }; |
| 73 | + |
| 74 | + if (typeof settings.offset == 'number') { |
| 75 | + settings.offset = { |
| 76 | + x: settings.offset, |
| 77 | + y: settings.offset |
| 78 | + }; |
| 79 | + } |
| 80 | + |
| 81 | + $template = buildGrowl(base); |
| 82 | + addContent($template, base.settings); |
| 83 | + placement($template, base.settings); |
| 84 | + bindControls($template, base.settings,plugin); |
| 85 | + }, |
| 86 | + buildGrowl = function(base) { |
| 87 | + |
| 88 | + var $template = $(base.settings.template); |
| 89 | + |
| 90 | + $template.addClass('alert-' + base.settings.type); |
| 91 | + $template.attr('data-growl-position', base.settings.placement.from + '-' + base.settings.placement.align); |
| 92 | + |
| 93 | + $template.find('[data-growl="dismiss"]').css('display', 'none'); |
| 94 | + $template.removeClass('alert-dismissable'); |
| 95 | + if (base.settings.allow_dismiss) { |
| 96 | + $template.addClass('alert-dismissable'); |
| 97 | + $template.find('[data-growl="dismiss"]').css('display', 'block'); |
| 98 | + } |
| 99 | + |
| 100 | + return $template; |
| 101 | + }, |
| 102 | + addContent = function($template, settings) { |
| 103 | + |
| 104 | + $template.find('[data-growl="dismiss"]').css({ |
| 105 | + 'z-index': ((settings.z_index-1) >= 1 ? (settings.z_index-1) : 1) |
| 106 | + }); |
| 107 | + |
| 108 | + if (settings.content.icon) { |
| 109 | + if (settings.icon_type.toLowerCase() == 'class') { |
| 110 | + $template.find('[data-growl="icon"]').addClass(settings.content.icon); |
| 111 | + }else{ |
| 112 | + if ($template.find('[data-growl="icon"]').is('img')) { |
| 113 | + $template.find('[data-growl="icon"]').attr('src', settings.content.icon); |
| 114 | + }else{ |
| 115 | + $template.find('[data-growl="icon"]').append('<img src="'+settings.content.icon+'" />'); |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | + |
| 120 | + if (settings.content.title) { |
| 121 | + $template.find('[data-growl="title"]').html(settings.content.title); |
| 122 | + } |
| 123 | + |
| 124 | + if (settings.content.message) { |
| 125 | + $template.find('[data-growl="message"]').html(settings.content.message); |
| 126 | + } |
| 127 | + |
| 128 | + if (settings.content.url) { |
| 129 | + $template.find('[data-growl="url"]').attr('href', settings.content.url).attr('target', settings.url_target); |
| 130 | + $template.find('[data-growl="url"]').css({ |
| 131 | + 'position': 'absolute', |
| 132 | + 'top': 0, |
| 133 | + 'left': 0, |
| 134 | + 'width': '100%', |
| 135 | + 'height': '100%', |
| 136 | + 'z-index': ((settings.z_index-2) >= 1 ? (settings.z_index-2) : 1) |
| 137 | + }); |
| 138 | + } |
| 139 | + }, |
| 140 | + placement = function($template, settings) { |
| 141 | + var offsetAmt = settings.offset.y, |
| 142 | + gCSS = { |
| 143 | + 'position': (settings.element === 'body' ? 'fixed' : 'absolute'), |
| 144 | + 'margin': 0, |
| 145 | + 'z-index': settings.z_index, |
| 146 | + 'display': 'inline-block' |
| 147 | + }, |
| 148 | + hasAnimation = false; |
| 149 | + |
| 150 | + $('[data-growl-position="' + settings.placement.from + '-' + settings.placement.align + '"]').each(function() { |
| 151 | + return offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + $(this).outerHeight() + settings.spacing); |
| 152 | + }); |
| 153 | + |
| 154 | + gCSS[settings.placement.from] = offsetAmt + "px"; |
| 155 | + $template.css(gCSS); |
| 156 | + |
| 157 | + if (settings.onShow) { |
| 158 | + settings.onShow(event); |
| 159 | + } |
| 160 | + |
| 161 | + $(settings.element).append($template); |
| 162 | + |
| 163 | + switch (settings.placement.align) { |
| 164 | + case 'center': |
| 165 | + $template.css({ |
| 166 | + 'left': '50%', |
| 167 | + 'marginLeft': -($template.outerWidth() / 2) + 'px' |
| 168 | + }); |
| 169 | + break; |
| 170 | + case 'left': |
| 171 | + $template.css('left', settings.offset.x + 'px'); |
| 172 | + break; |
| 173 | + case 'right': |
| 174 | + $template.css('right', settings.offset.x + 'px'); |
| 175 | + break; |
| 176 | + } |
| 177 | + $template.addClass('growl-animated'); |
| 178 | + |
| 179 | + $template.one('webkitAnimationStart oanimationstart MSAnimationStart animationstart', function(event) { |
| 180 | + hasAnimation = true; |
| 181 | + }); |
| 182 | + |
| 183 | + $template.one('webkitAnimationEnd oanimationend MSAnimationEnd animationend', function(event) { |
| 184 | + if (settings.onShown) { |
| 185 | + settings.onShown(event); |
| 186 | + } |
| 187 | + }); |
| 188 | + |
| 189 | + setTimeout(function() { |
| 190 | + if (!hasAnimation) { |
| 191 | + if (settings.onShown) { |
| 192 | + settings.onShown(event); |
| 193 | + } |
| 194 | + } |
| 195 | + }, 600); |
| 196 | + }, |
| 197 | + bindControls = function($template, settings, plugin) { |
| 198 | + $template.addClass(settings.animate.enter); |
| 199 | + |
| 200 | + $template.find('[data-growl="dismiss"]').on('click', function() { |
| 201 | + plugin.close(); |
| 202 | + }); |
| 203 | + |
| 204 | + $template.on('mouseover', function(e) { |
| 205 | + $template.addClass('hovering'); |
| 206 | + }).on('mouseout', function() { |
| 207 | + $template.removeClass('hovering'); |
| 208 | + }); |
| 209 | + |
| 210 | + if (settings.delay >= 1) { |
| 211 | + $template.data('growl-delay', settings.delay); |
| 212 | + var timer = setInterval(function() { |
| 213 | + |
| 214 | + var delay = parseInt($template.data('growl-delay')) - settings.timer; |
| 215 | + if ((!$template.hasClass('hovering') && settings.mouse_over == 'pause') || settings.mouse_over != 'pause') { |
| 216 | + $template.data('growl-delay', delay); |
| 217 | + } |
| 218 | + |
| 219 | + if (delay <= 0) { |
| 220 | + clearInterval(timer); |
| 221 | + plugin.close(); |
| 222 | + } |
| 223 | + }, settings.timer); |
| 224 | + } |
| 225 | + }; |
| 226 | + |
| 227 | + // Avoid Plugin.prototype conflicts |
| 228 | + Plugin.prototype = { |
| 229 | + update: function(command, update) { |
| 230 | + switch (command) { |
| 231 | + case 'icon': |
| 232 | + if (this.settings.icon_type.toLowerCase() == 'class') { |
| 233 | + this.$template.find('[data-growl="icon"]').removeClass(this.settings.content.icon); |
| 234 | + this.$template.find('[data-growl="icon"]').addClass(update); |
| 235 | + }else{ |
| 236 | + if (this.$template.find('[data-growl="icon"]').is('img')) { |
| 237 | + this.$template.find('[data-growl="icon"]') |
| 238 | + }else{ |
| 239 | + this.$template.find('[data-growl="icon"]').find('img').attr().attr('src', update); |
| 240 | + } |
| 241 | + } |
| 242 | + break; |
| 243 | + case 'url': |
| 244 | + this.$template.find('[data-growl="url"]').attr('href', update); |
| 245 | + break; |
| 246 | + case 'type': |
| 247 | + this.$template.removeClass(function (index, css) { |
| 248 | + return (css.match (/(^|\s)alert-\S+/g) || []).join(' '); |
| 249 | + }); |
| 250 | + this.$template.addClass('alert-' + update); |
| 251 | + break; |
| 252 | + default: |
| 253 | + this.$template.find('[data-growl="' + command +'"]').html(update); |
| 254 | + } |
| 255 | + |
| 256 | + return this; |
| 257 | + }, |
| 258 | + close: function() { |
| 259 | + var base = this.$template, |
| 260 | + settings = this.settings, |
| 261 | + posX = base.css(settings.placement.from), |
| 262 | + hasAnimation = false; |
| 263 | + |
| 264 | + if (settings.onHide) { |
| 265 | + settings.onHide(event); |
| 266 | + } |
| 267 | + |
| 268 | + base.addClass(this.settings.animate.exit); |
| 269 | + |
| 270 | + base.nextAll('[data-growl-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]').each(function() { |
| 271 | + $(this).css(settings.placement.from, posX); |
| 272 | + posX = (parseInt(posX)+(settings.spacing)) + $(this).outerHeight(); |
| 273 | + }); |
| 274 | + |
| 275 | + base.one('webkitAnimationStart oanimationstart MSAnimationStart animationstart', function(event) { |
| 276 | + hasAnimation = true; |
| 277 | + }); |
| 278 | + |
| 279 | + base.one('webkitAnimationEnd oanimationend MSAnimationEnd animationend', function(event) { |
| 280 | + $(this).remove(); |
| 281 | + if (settings.onHidden) { |
| 282 | + settings.onHidden(event); |
| 283 | + } |
| 284 | + }); |
| 285 | + |
| 286 | + setTimeout(function() { |
| 287 | + if (!hasAnimation) { |
| 288 | + base.remove(); |
| 289 | + if (settings.onHidden) { |
| 290 | + settings.onHidden(event); |
| 291 | + } |
| 292 | + } |
| 293 | + }, 100); |
| 294 | + |
| 295 | + return this; |
| 296 | + } |
| 297 | + }; |
| 298 | + |
| 299 | + // A really lightweight plugin wrapper around the constructor, |
| 300 | + // preventing against multiple instantiations |
| 301 | + $.growl = function ( content, options ) { |
| 302 | + if (content == false && options.command == "closeAll") { |
| 303 | + closeAll(options.position); |
| 304 | + return false; |
| 305 | + }else if (content == false) { |
| 306 | + setDefaults(this, options); |
| 307 | + return false; |
| 308 | + } |
| 309 | + var plugin = new Plugin( this, content, options ); |
| 310 | + return plugin; |
| 311 | + }; |
| 312 | + |
| 313 | +})( jQuery, window, document ); |
0 commit comments