jboesch / gritter Goto Github PK
View Code? Open in Web Editor NEWA small growl-like notification plugin for jQuery
Home Page: http://boedesign.com/2009/07/11/growl-for-jquery-gritter/
A small growl-like notification plugin for jQuery
Home Page: http://boedesign.com/2009/07/11/growl-for-jquery-gritter/
Can this be used in commercial, open source softwares?
This plugin is awesome, thank you!
The http://boedesign.com/ link does not resolve. (No dns)
I wanted to be able to add an 'onclick' event to notifications, which I accomplished by adding this code to the Gritter.add function (around line 180)
//Bind onclick handler if provided in params
if ($.isFunction(params.onclick)) {
$(item).bind('click', function(event){
params.onclick.call(event, item);
});
};
// Clicking (X) makes the perdy thing close
$(item).find('.gritter-close').click(function(e){
Gritter.removeSpecific(number, {}, null, true);
//make sure that onclick function of item is not called
e.preventDefault();
return false;
});
I had to modify the close button function, because clicking the close button would cause annoying event bubbling...
It seems the website linked that explains the proper way to use the library is down, but was copied to the repo's Wiki page here.
Would you be against accepting a PR that points towards the WIki page and / or changing the http://boedesign.com links to the Wiki page?
If you're planning on bringing the site back this might not be such a big issue, but it might be good to have changed in the meantime.
Is there any active work on better support for mobile devices?
Hi,
Can you add an open source license to this. I'd love to use it but the license is unclear?
Stew
The gritter-light.png image has a small issue which causes there to be a small patch of white at the bottom of the close icon. I have a fixed image, but I'm not sure if I can attach things to these bug reports...
but it's empty
Awesome plugin!
If you have a long page that has a vertical scroll bar and a action you down there triggers a gritter, gritter causes the page to scroll back to the top. It would be nice to have the page just stay where it is. Some actions on my site cause a visual change on pages down there but when gritter causes the page to jump to the top you miss seeing those changes. You have to scroll back down to see them.
Please compress the jquery.gritter.css into jquery.gritter.min.css.
We really need it ๐บ
Hi. I was struggling with HTTP 404 error caused by gritter's CSS. On line 33 the stylesheet tries to load the "." path which is the folder of the css. Some applications, for example my rails one, when the stylesheet tries to load the path returns the mentioned error. It is deeply discussed here http://duckranger.com/2010/06/getting-404-with-jquery-gritter/ Please check it out and fix it for future comers. Thanks
Hi,
Curious if it's possible to have multiple locations on screen, but in different locations; Say a fixed Message in the top left and a popup occuring every now in then in the bottom right.
I can pull this off with jQuery, but curious if support like this might be enabled (or planned to be).
Thanks!
How I can use this perfect plugin with i18n?
Thx.
Hi,
can you add a method to update the subset of the options, like notification content, header of notification, ... ?
Hello,
Gritter seems not working with jQuery 1.4.2, the mouse pointer flinks on the close button and unable to close the notification after all.
All the best.
Hey, I'd love to use this, but there's no license, so I'm breaking copyright law if I do.
I gather that isn't your intent, so maybe just bogard the license from jQuery and change the names/dates (dual GPL/MIT is an excellent choice for me :)
Cheers.
I have this very simple code
$.gritter.add({
'title': 'Test',
'text': 'test',
'position': 'bottom-right',
'sticky': false
});
The problem is that it is not showing on the bottom right. It is still showing on the upper right.
In fact, I tried upper-left, bottom-left and bottom-right and it is still on the upper right.
Curious if Gritter is present/uploaded in a cdn ( like cdnjs.com , say ) to pull the versions from the same.
Would help integration much, in that case.
Thanks in advance.
I'm using the notifications on an application which has a lot of data on the page. When users scroll down the page and do something which (via ajax) generates a notification, the page goes back to the top to display. Is there a way to stop it running to the top all of the time and just displaying the notification top right wherever the page may be?
[del]
Great plugin! Think you'll add jQuery Themeroller support?
You have property to change the position of the popup but it is not hooked up from what I can tell. I made the following change to line 113 in the "add" function to make it work properly:
(old)
position = $.gritter.options.position,
(new working)
position = params.position || $.gritter.options.position,
please have a look at this and let me know if I am mis-using your module. maybe there is a different way to set position that I didn't find.
if you want, i can submit a PR with this change. thanks!
We'd like to use rails-assets to include Gritter in our app, but it requires releases to be tagged in order to be definitively tied to a version when building a gem.
Could you create a 1.7.4
tag for the current state of master
? Thanks!
Gritter dont work anymore on browser "Brave".
Hello,
I was trying to specify the position option when adding a new notification but by looking at the source code I saw that you're doing this (add method - around line 107):
position = $.gritter.options.position
I just want to know if there is any restriction that is preventing you to do something like:
position = params.position||$.gritter.options.position
Allowing different notices to be displayed in different positions.
Thanks in advance!
[del]
It would be great to be able to make the notifications actionable, so that clicking on the body of the notification (not the X) will take you to some URL. In other words, I'd like to be able to do something like this:
$.gritter.add({
title: 'New Comment',
text: 'There has been a new comment on your post.',
link: '/posts/1/',
sticky: true
})
In this example, If the user clicked on this sticky notification, it would take them to /posts/1/.
Is this something that you would consider adding?
do more!
Gritter doesn't show on the first call, then works OK after second call.
Demo page shows the same problem.
Currently the wrapper element is added to the body by default. In my case, I wanted to have another parent element. So I added an option: "parent_element", which default value is 'body'
I just put the whole Javascript here, because I have no clue of how to add the patch :(
/*
* Gritter for jQuery
* http://www.boedesign.com/
*
* Copyright (c) 2012 Jordan Boesch
* Dual licensed under the MIT and GPL licenses.
*
* Date: February 24, 2012
* Version: 1.7.4
*/
(function($){
/**
* Set it up as an object under the jQuery namespace
*/
$.gritter = {};
/**
* Set up global options that the user can over-ride
*/
$.gritter.options = {
position: '',
class_name: '', // could be set to 'gritter-light' to use white notifications
fade_in_speed: 'medium', // how fast notifications fade in
fade_out_speed: 1000, // how fast the notices fade out
time: 6000, // hang on the screen for...
parent_element: 'body' // the element to which the wrapper will appended
}
/**
* Add a gritter notification to the screen
* @see Gritter#add();
*/
$.gritter.add = function(params){
try {
return Gritter.add(params || {});
} catch(e) {
var err = 'Gritter Error: ' + e;
(typeof(console) != 'undefined' && console.error) ?
console.error(err, params) :
alert(err);
}
}
/**
* Remove a gritter notification from the screen
* @see Gritter#removeSpecific();
*/
$.gritter.remove = function(id, params){
Gritter.removeSpecific(id, params || {});
}
/**
* Remove all notifications
* @see Gritter#stop();
*/
$.gritter.removeAll = function(params){
Gritter.stop(params || {});
}
/**
* Big fat Gritter object
* @constructor (not really since its object literal)
*/
var Gritter = {
// Public - options to over-ride with $.gritter.options in "add"
position: '',
fade_in_speed: '',
fade_out_speed: '',
time: '',
// Private - no touchy the private parts
_custom_timer: 0,
_item_count: 0,
_is_setup: 0,
_tpl_close: '<div class="gritter-close"></div>',
_tpl_title: '<span class="gritter-title">[[title]]</span>',
_tpl_item: '<div id="gritter-item-[[number]]" class="gritter-item-wrapper [[item_class]]" style="display:none"><div class="gritter-top"></div><div class="gritter-item">[[close]][[image]]<div class="[[class_name]]">[[title]]<p>[[text]]</p></div><div style="clear:both"></div></div><div class="gritter-bottom"></div></div>',
_tpl_wrap: '<div id="gritter-notice-wrapper"></div>',
/**
* Add a gritter notification to the screen
* @param {Object} params The object that contains all the options for drawing the notification
* @return {Integer} The specific numeric id to that gritter notification
*/
add: function(params){
// Handle straight text
if(typeof(params) == 'string'){
params = {text:params};
}
// We might have some issues if we don't have a title or text!
if(!params.text){
throw 'You must supply "text" parameter.';
}
// Check the options and set them once
if(!this._is_setup){
this._runSetup();
}
// Basics
var title = params.title,
text = params.text,
image = params.image || '',
sticky = params.sticky || false,
item_class = params.class_name || $.gritter.options.class_name,
position = $.gritter.options.position,
time_alive = params.time || '';
this._verifyWrapper();
this._item_count++;
var number = this._item_count,
tmp = this._tpl_item;
// Assign callbacks
$(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){
Gritter['_' + val + '_' + number] = ($.isFunction(params[val])) ? params[val] : function(){}
});
// Reset
this._custom_timer = 0;
// A custom fade time set
if(time_alive){
this._custom_timer = time_alive;
}
var image_str = (image != '') ? '<img src="' + image + '" class="gritter-image" />' : '',
class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image';
// String replacements on the template
if(title){
title = this._str_replace('[[title]]',title,this._tpl_title);
}else{
title = '';
}
tmp = this._str_replace(
['[[title]]', '[[text]]', '[[close]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'],
[title, text, this._tpl_close, image_str, this._item_count, class_name, item_class], tmp
);
// If it's false, don't show another gritter message
if(this['_before_open_' + number]() === false){
return false;
}
$('#gritter-notice-wrapper').addClass(position).append(tmp);
var item = $('#gritter-item-' + this._item_count);
item.fadeIn(this.fade_in_speed, function(){
Gritter['_after_open_' + number]($(this));
});
if(!sticky){
this._setFadeTimer(item, number);
}
// Bind the hover/unhover states
$(item).bind('mouseenter mouseleave', function(event){
if(event.type == 'mouseenter'){
if(!sticky){
Gritter._restoreItemIfFading($(this), number);
}
}
else {
if(!sticky){
Gritter._setFadeTimer($(this), number);
}
}
Gritter._hoverState($(this), event.type);
});
// Clicking (X) makes the perdy thing close
$(item).find('.gritter-close').click(function(){
Gritter.removeSpecific(number, {}, null, true);
});
return number;
},
/**
* If we don't have any more gritter notifications, get rid of the wrapper using this check
* @private
* @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback
* @param {Object} e The jQuery element that we're going to perform the remove() action on
* @param {Boolean} manual_close Did we close the gritter dialog with the (X) button
*/
_countRemoveWrapper: function(unique_id, e, manual_close){
// Remove it then run the callback function
e.remove();
this['_after_close_' + unique_id](e, manual_close);
// Check if the wrapper is empty, if it is.. remove the wrapper
if($('.gritter-item-wrapper').length == 0){
$('#gritter-notice-wrapper').remove();
}
},
/**
* Fade out an element after it's been on the screen for x amount of time
* @private
* @param {Object} e The jQuery element to get rid of
* @param {Integer} unique_id The id of the element to remove
* @param {Object} params An optional list of params to set fade speeds etc.
* @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X)
*/
_fade: function(e, unique_id, params, unbind_events){
var params = params || {},
fade = (typeof(params.fade) != 'undefined') ? params.fade : true,
fade_out_speed = params.speed || this.fade_out_speed,
manual_close = unbind_events;
this['_before_close_' + unique_id](e, manual_close);
// If this is true, then we are coming from clicking the (X)
if(unbind_events){
e.unbind('mouseenter mouseleave');
}
// Fade it out or remove it
if(fade){
e.animate({
opacity: 0
}, fade_out_speed, function(){
e.animate({ height: 0 }, 300, function(){
Gritter._countRemoveWrapper(unique_id, e, manual_close);
})
})
}
else {
this._countRemoveWrapper(unique_id, e);
}
},
/**
* Perform actions based on the type of bind (mouseenter, mouseleave)
* @private
* @param {Object} e The jQuery element
* @param {String} type The type of action we're performing: mouseenter or mouseleave
*/
_hoverState: function(e, type){
// Change the border styles and add the (X) close button when you hover
if(type == 'mouseenter'){
e.addClass('hover');
// Show close button
e.find('.gritter-close').show();
}
// Remove the border styles and hide (X) close button when you mouse out
else {
e.removeClass('hover');
// Hide close button
e.find('.gritter-close').hide();
}
},
/**
* Remove a specific notification based on an ID
* @param {Integer} unique_id The ID used to delete a specific notification
* @param {Object} params A set of options passed in to determine how to get rid of it
* @param {Object} e The jQuery element that we're "fading" then removing
* @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave
*/
removeSpecific: function(unique_id, params, e, unbind_events){
if(!e){
var e = $('#gritter-item-' + unique_id);
}
// We set the fourth param to let the _fade function know to
// unbind the "mouseleave" event. Once you click (X) there's no going back!
this._fade(e, unique_id, params || {}, unbind_events);
},
/**
* If the item is fading out and we hover over it, restore it!
* @private
* @param {Object} e The HTML element to remove
* @param {Integer} unique_id The ID of the element
*/
_restoreItemIfFading: function(e, unique_id){
clearTimeout(this['_int_id_' + unique_id]);
e.stop().css({ opacity: '', height: '' });
},
/**
* Setup the global options - only once
* @private
*/
_runSetup: function(){
for(opt in $.gritter.options){
this[opt] = $.gritter.options[opt];
}
this._is_setup = 1;
},
/**
* Set the notification to fade out after a certain amount of time
* @private
* @param {Object} item The HTML element we're dealing with
* @param {Integer} unique_id The ID of the element
*/
_setFadeTimer: function(e, unique_id){
var timer_str = (this._custom_timer) ? this._custom_timer : this.time;
this['_int_id_' + unique_id] = setTimeout(function(){
Gritter._fade(e, unique_id);
}, timer_str);
},
/**
* Bring everything to a halt
* @param {Object} params A list of callback functions to pass when all notifications are removed
*/
stop: function(params){
// callbacks (if passed)
var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){};
var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){};
var wrap = $('#gritter-notice-wrapper');
before_close(wrap);
wrap.fadeOut(function(){
$(this).remove();
after_close();
});
},
/**
* An extremely handy PHP function ported to JS, works well for templating
* @private
* @param {String/Array} search A list of things to search for
* @param {String/Array} replace A list of things to replace the searches with
* @return {String} sa The output
*/
_str_replace: function(search, replace, subject, count){
var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
f = [].concat(search),
r = [].concat(replace),
s = subject,
ra = r instanceof Array, sa = s instanceof Array;
s = [].concat(s);
if(count){
this.window[count] = 0;
}
for(i = 0, sl = s.length; i < sl; i++){
if(s[i] === ''){
continue;
}
for (j = 0, fl = f.length; j < fl; j++){
temp = s[i] + '';
repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
s[i] = (temp).split(f[j]).join(repl);
if(count && s[i] !== temp){
this.window[count] += (temp.length-s[i].length) / f[j].length;
}
}
}
return sa ? s : s[0];
},
/**
* A check to make sure we have something to wrap our notices with
* @private
*/
_verifyWrapper: function(){
if($('#gritter-notice-wrapper').length == 0){
$($.gritter.options.parent_element).append(this._tpl_wrap);
}
}
}
})(jQuery);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.