Snarl

Growl-style notifications for your web app.

Currently v0.3.3

Snarl Notifications

Snarl intends to make it quick and easy to include gorgeous and functional Mac/Growl-style notifications in your web app. It supports desktop, touch/tablet, and mobile devices; has raw JS and LESS/CSS source files; and supports custom timeouts and notification click callbacks. Ripple/wave click effect brought by Waves!

Download View on Github

Getting Started

Download the Files

Hit the download link above and in the downloaded snarl.zip file will be source and minified versions of the JS, CSS and optionally the LESS files too.

Clone the Repo

Another method of getting the files is cloning the repo via git clone https://github.com/hoxxep/Snarl. You'll find the files which can be used in projects inside the dist/ folder. If you have cloned the repo and are modifying the source files to suit your project's aesthetic, instead of editing files in the dist folder, edit them inside the src/ folder. Then, in the Snarl repo root directory (provided you have node installed) you can run npm install, npm install -g gulp, gulp and this will watch the source files and rebuild the dist files if any changes occur - automatically compiling the LESS and minifying the source files.

Adding the Files to Your Project

Snarl gives you pre-minified versions of the CSS and JS for immediate embedding into projects. Otherwise, the raw files are still there in case you want to edit them. Included is also snarl.less which is the source for the compiled CSS, modifying this is the fastest way to change the aesthetic of the notification design or animations to suit your project.

Check out the demos below for usage examples.

Snarl Notification Demos

Note: Snarl itself does not require jQuery as a dependency, but these examples use jQuery for the click events for clarity.

Basic Demo

Adding a notification is really simple with snarl. Specify a title and some text (as a description) and your notification will appear!

$('#basic-demo').click(function() {
    Snarl.addNotification({
        title: 'Ahoy there, Skipper',
        text: 'Hello, world!'
    });
});

Icons

Snarl supports optional custom icons in the form of images, SVGs, and glyphicon fonts (such as FontAwesome). For a circular icon you can add a class/style on the image/svg/glyphicon which applies border-radius:50%; to the icon.

$('#icon-demo').click(function() {
    Snarl.addNotification({
        title: 'Custom Icons',
        text: 'Cool, huh? Supports images, svgs, and glyphicon fonts.',
        icon: '<i class="fa fa-globe"></i>'
    });
});

Timeouts

Snarl supports custom timeouts specified in milliseconds or even having no timeouts at all.

Custom Timeout

$('#custom-timeout-demo').click(function() {
    Snarl.addNotification({
        title: 'Custom Timeouts',
        text: 'This notification has an 8000ms timeout!',
        icon: '<i class="fa fa-clock-o"></i>',
        timeout: 8000
    });
});

No Timeout

Notifications with no timeouts must either be manually dismissed by the user, or can be removed by your code once an event is complete. Updating notifications is done using the ID string returned by Snarl.addNotification().

var noTimeoutNotification = null;
$('#no-timeout-open').click(function() {
    if (Snarl.isDismissed(noTimeoutNotification)) {
        noTimeoutNotification = Snarl.addNotification({
            title: 'No Timeout',
            text: 'Close the notification by pressing either the dismiss button on the page or in the notification.',
            icon: '<i class="fa fa-ban"></i>',
            timeout: null
        });
    }
});
$('#no-timeout-close').click(function() {
    Snarl.removeNotification(noTimeoutNotification);
});

Update Notifications

Because notifications are track/modifiable with their IDs, notifications can be updated, reopened, and removed. All options on a notification can be updated later by resupplying the options you wish to change with the Snarl.editNotification(id, options) function.

/**
 * Take user input
 */
function options() {
    var title = $('#update-notification-title').val(),
        text = $('#update-notification-text').val(),
        icon = $('#update-notification-icon').val(),
        timeout = $('#update-notification-timeout').val(),
        dismissable = $('#update-notification-dismissable').prop('checked');

    if (title === '') title = 'Notification Title';
    if (text === '') text = 'Notification Text';
    if (timeout === '') timeout = null;

    return {
        title: title,
        text: text,
        icon: icon,
        timeout: timeout,
        dismissable: dismissable
    };
}

/**
 * Snarl-related code
 */
var notification = null;
$('#update-notification-open').click(function() {
    if (!Snarl.exists(notification)) {
        notification = Snarl.addNotification(options());
    } else {
        Snarl.editNotification(notification, options());
    }
});
$('#update-notification-close').click(function() {
    Snarl.removeNotification(notification);
});

Click Actions/Callbacks

If the user clicks a notification, an action can be run. Either a callback function can be executed; a url can be visited; or nothing. These are specified via the action option. If a function is provided it will be used as a callback, if a string is provided then that url will be visited, or if null is used then no action will occur. The default value is action: null.

Action: String/Url

Visit a url when the user clicks the notification. Note: currently does this by setting window.location.

$('#snarl-callback-string').click(function() {
    Snarl.addNotification({
        title: 'String Callback',
        text: 'Click this notification to visit a url',
        icon: '<i class="fa fa-github fa-lg"></i>'
        action: 'http://github.com/hoxxep/Snarl'
    });
});

Action: Callback Function

This example makes the notification update itself once clicked. The function is passed the notification id as an argument, and has the potential to work with JS MVC frameworks too. Note that if the dismiss button is pressed, then no callback is triggered (subject to change).

$('#snarl-callback-function').click(function() {
    var id = Snarl.addNotification({
        title: 'Snarl Notification #' + (Snarl.count + 1),
        text: 'Hello, world! Click this notification.',
        icon: '<i class="fa fa-dot-circle-o"></i>',
        timeout: null,
        action: function(id) {
            Snarl.editNotification(id, {
                text: 'You clicked the notification! Click once more, click the dismiss button, or wait 8000ms to close it.',
                icon: '<i class="fa fa-check-circle"></i>',
                timeout: 8000,
                action: function(id) {
                    Snarl.removeNotification(id);
                }
            });
        }
    });
});

Messages Demo

The messages demo is a simple example using jQuery to demo how Snarl notifications could look in a more realistic usage example.

var typingNotification = null;
$('#name').focusout(function() {
    typingNotification = null;
    if ($('#name').val()) {
        Snarl.addNotification({
            title: $(this).val(),
            text: 'Signed in',
            icon: '<i class="fa fa-user-plus"></i>'

        });
    }
});
$('#message').keypress(function() {
    if ($('#name').val()) {
        if (typingNotification === null) {
            typingNotification = Snarl.addNotification({
                title: $('#name').val(),
                text: 'Is typing...',
                icon: '<i class="fa fa-pencil"></i>',
                timeout: 2000
            });
        } else {
            Snarl.reOpenNotification(typingNotification);
        }
    }
});
$('#send-message').click(function() {
    if ($('#name').val() && $('#message').val()) {
        Snarl.removeNotification(typingNotification);
        typingNotification = null;
        Snarl.addNotification({
            title: $('#name').val(),
            text: $('#message').val(),
            icon: '<i class="fa fa-comment"></i>',
            timeout: 5000
        });
        $('#message').val('');
    } else {
        Snarl.addNotification({
            title: 'Error',
            text: 'No name or message entered!',
            icon: '<i class="fa fa-warning"></i>'
        });
    }
});

Snarl Notification Reference

Common Function Arguments

Argument: id

The id is the string which maps to a Snarl notification. ids are generated and returned automatically when using .addNotification(options).

Argument: options

title: String - title of the notification.

text: String - description part of the notification.

icon: String/HTML - HTML string for an image/svg/glyphicon element to use as a notification icon.

timeout: Integer/null

action: String/Function/null

dismissable: true/false whether the notification is dismissable

Default Options

Snarl.defaultOptions => {
    title: '',
    text: '',
    icon: '',
    timeout: 3000,
    action: null,
    dismissable: true
}

Example Options

Note: for user friendliness, most notifications should be dismissable (and they are by default), hence why dismissable is omitted in this example.

var options = {
    title: 'Snarl Notification',
    text: 'Hello, world! This is an example notification.',
    icon: '<i class="fa fa-info-circle"></i>',
    action: function(id) {
        // do relevant action in web app
        console.log('Snarl notification ' + id + ' was clicked!');
    }
};

Snarl Methods

.setDefaultOptions(options)

Set's the default options to be used when adding a new notification.

// Example: Set default timeout to null
Snarl.setDefaultOptions({
    timeout: null
});

.setNotificationHTML(html_string)

Customise the inner HTML generated for a notification. Notifications automatically have the class .snarl-notification and id #snarl-notification-[id] added. ([id] is the notification ID string returned by .addNotification()).

Note: notifications must have the snarl-title, snarl-text, and snarl-close classes to hold the title and text, and to have a working close button.

// Example: Very basic custom notification HTML with Waves support and a FontAwesome close icon
Snarl.setNotificationHTML(
    '<div class="waves-effect">' +
        '<h3 class="snarl-title"></h3>' +
        '<p class="snarl-text"></p>' +
        '<div class="snarl-close waves-effect">' +
            '<i class="fa fa-close"></i>' +
        '</div>'
    '</div>'
);

.addNotification(options) : String id

Open a new notification with the specified options. Returns a string that is the notification id.

// Example: Add new notification
var notification = Snarl.addNotification({
    title: 'Snarl Notification',
    text: 'Example notification text',
    action: 'http://hoxxep.github.io/Snarl'
});

.editNotification(id, options)

Edit an open notification. Only supply the options that you want to update, the rest will stay the same. If the notification has been dismissed it will re-open the notification with the previous timeout setting.

// Example: Edit the description on our new notification
Snarl.editNotification(notification, {
    text: 'I\'ve edited the notification text!'
});

.reOpenNotification(id)

Attempt to re-open a notification otherwise, if the notification is still open, reset the timeout.

// Example: Re-open the notification if it was dismissed
Snarl.reOpenNotification(notification);

.removeNotification(id) : Boolean successful

Dismiss a notification. Returns true if the notification was open and false if it was already dismissed or did not exist. Note removed notifications can still be re-opened or edited, this merely dismisses a notification. Will probably be refactored to .dismissNotification in the near future.

// Example: Manually dismiss the notification
Snarl.removeNotification(notification);

.isDismissed(id) : Boolean dismissed

Checks if a notification is open. Returns true if the notification has been dismissed or does not exist.

// Example: Because we dismissed/removed the notification .isDismissed is true
Snarl.isDismissed(notification) // => true

.exists(id) : Boolean exists

Check if a notification id has been used. Returns true if notification has been opened with that id even if it's been dismissd.

// Example: Notification with our id still exists, even after being
// dismissed/removed. This means the notification can still be re-opened.
Snarl.exists(notification) // => true

.setTitle(id, title)

Set the title of a notification. Shorthand for .editNotification(id, {title: title}).

// Example: Change the title of our notification
// Note: this will re-open/reset the timeout on our notification to it's current setting.
Snarl.setTitle(notification, 'Changed the title!');

.setText(id, text)

Set the text of a notification. Shorthand for .editNotification(id, {text: text}).

// Example: Change the text of our notification
// Note: this will re-open/reset the timeout on our notification to it's current setting.
Snarl.setText(notification, 'Changed the text!');

.setIcon(id, icon)

Set the icon of a notification. Shorthand for .editNotification(id, {icon: icon}).

// Example: Change the icon of our notification
// Note: this will re-open/reset the timeout on our notification to it's current setting.
Snarl.setIcon(notification, '<i class="fa fa-info-circle"></i>');

.setTimeout(id, timeout)

Set the timeout of a notification. Shorthand for .editNotification(id, {timeout: timeout}).

// Example: Remove the timeout altogether
// Note: this will re-open/reset the timeout on our notification.
Snarl.setTimeout(notification, null);
// Example: Make timeout 8000ms
// Note: this will re-open/reset the timeout on our notification.
Snarl.setTimeout(notification, 8000);