1.4.1
Messenger is different from other solutions for a few reasons:
Messenger is accessed through a global Messenger object. The object is called at each usage to give
it a chance to instantiate if necessary.
The most basic usage is to post a message:
Messenger().post({ options })
Options can be a string representing the body of the message:
Messenger().post("Welcome to the darkside (tm)")
It can also be an object:
Messenger().post({
message: "How's it going?",
type: "error"
})
The full list of options:
message: The text of the messagetype: info, error or success are understood by the provided themes. You can also pass your
own string, and that class will be added.theme: What theme class should be applied to the message? Defaults to the theme set for Messenger in
general.id: A unique id. If supplied, only one message with that ID will be shown at a time.singleton: Hide the newer message if there is an id collision, as opposed to the older message.actions: Action links to put in the message, see the 'Actions' section on this page.hideAfter: Hide the message after the provided number of secondshideOnNavigate: Hide the message if Backbone client-side navigation occursshowCloseButton: Should a close button be added to the message?closeButtonText: Specify the text the close button should use (default ×)Messenger also includes aliases which set the type for you: Messenger().error(), Messenger().success(), and messenger().info().
Rather than posting a new message when progress occurs, it can be nice to update an existing message.
.post, along with the other message posting methods, provide a Message instance which has the
following methods:
show(): Show the message, if it's hiddenhide(): Hide the message, if it's showncancel(): If the message is associated with an ajax request or is counting down to retry, cancel itupdate({ options }): Update the message with the provided optionsAny option, such as type or message can be changed with update:
message = Messenger().post("Calculating position")
message.update({
type: "error",
message: "Error calculating position"
})
When Messenger is called, it creates, if necessary, a container for future messages to be placed into.
Messenger can be passed options to configure the container when it's first called, future calls will
alter the existing container.
Messenger options:
extraClasses: Extra classes to be appended to the container. These can be used to configure the active theme.
If you'd like the messenger box to be overlayed on the screen, you should provide the messenger-fixed class along with any of
the following positioning classes: messenger-on-bottom, messenger-on-top, messenger-on-left, messenger-on-right.
Adding the top or bottom class along with a left or right will move the messenger dialog into the specified corner.maxMessages: The maximum number of messages to show at onceparentLocations: Which locations should be tried when inserting the message container into the page. The default is ['body'].
It accepts a list to allow you to try a variety of places when deciding what the optimal location is on any given page. This should
generally not need to be changed unless you are inserting the messages into the flow of the document, rather than using messenger-fixed.theme: What theme are you using? Some themes have associated javascript, specifing this allows that js to run.messageDefaults: Default options for created messagesMessenger({
parentLocations: ['.page'], // Let's insert it into the page
extraClasses: '' // And not add the fixed classes
})
// Future calls just need to refer to Messenger(), they'll get the same instance
Messenger({
// Let's put the messenger in the top left corner
extraClasses: 'messenger-fixed messenger-on-left messenger-on-top'
});
The object provided by Messenger() also has a couple of additional methods:
hideAll: Hide all messagesrun: See 'Running Things' belowajax: See 'Running Things' belowexpectPromise: See 'Running Things' belowhookBackboneAjax: See Backbone belowOne of the most common use cases for messenger is to show the progress and success or error of an asynchronous action, like an ajax request.
Messenger includes a method to help with that, run.
run({ messageOptions }, { actionOptions })
messageOptions:
action: The function which should be passed actionOptions. success and error callbacks will be added to actionOptions
and used to show the appropriate messages.successMessage: What message should be shown if the action is a success? Can be a string, or false if no message should be shown. Can also
be a function returning a string, message options object, or false.errorMessage: Same as success message, but shown after the error callback is called.progressMessage: A message to be shown while the action is underway, or false.showSuccessWithoutError: Set to false if you only want the success message to be shown if the success comes after a failureignoredErrorCodes: By default the error handler looks for xhr.status, assuming the action is $.ajax. If it is, this can be set to an
array of HTTP status codes which should not be considered an error.returnsPromise: If true, instead of wrapping the success and error callbacks passed to action, we expect action to return to
us a promise, and use that to show the appropriate messages.retry: Set to false to not have the action retried if it fails. Or set it to an object with the following options:allow: Should we show a manual 'Retry' button?auto: Should we automatically start the retry timer after a failure?Your success and error handlers can return false if they don't wish the message to be shown. They can also return a string to change the message, or an object to change more message options.
Messenger().run({
action: $.ajax,
successMessage: 'Contact saved',
errorMessage: 'Error saving contact',
progressMessage: 'Saving contact...'
}, {
/* These options are provided to $.ajax, with success and error wrapped */
url: '/contact',
data: contact,
error: function(resp){
if (resp.status === 409)
return "A contact with that email already exists";
}
});
We also provide a couple of aliases:
Messenger().ajax({ messageOptions }, { actionOptions }): Call run with $.ajax as the action (which is already the default).Messenger().expectPromise(action, { messageOptions }): Call run with a function which returns a promise, so actionOptions aren't necessary.Messenger().expectPromise(function(){
return $.ajax({
url: '/aliens/44',
type: 'DELETE'
});
}, {
successMessage: 'Alien Destroyed!',
progressMessage: false
});
All three methods return a Message instance. You can call message.cancel() to stop the retrying, if necessary.
You can pass messages a hash of actions the user can execute on the message. For example, run will add 'Retry' and 'Cancel'
buttons to error messages which have retry enabled.
Actions are provided as the actions hash to post or run:
msg = Messenger().post({
message: "Are you sure you'd like to delete this contact?",
actions: {
delete: {
label: "Delete",
action: function(){
delete()
msg.hide()
}
},
cancel: {
action: function(){
msg.hide()
}
}
}
})
You can add DOM event handlers to the message itself, or any element within it. For example, you might wish to do something when the user clicks on the message.
The format of the event key is: "[type] event [selector]"
Type is a message type, like success, error, or info, or skip to ignore the type. It's useful with run where
the same options are getting applied to the success and error messages.
Event is the DOM event to bind to.
Selector is any jQuery selector, or skip to bind to the message element itsef.
Messenger().post({
message: "Click me to explode!",
events: {
"click": function(e){
explode();
},
"hover a.button": function(e){
e.stopPropagation();
}
}
});
Messenger includes a function to hook into Backbone.js' sync method. To enable it, call Messenger().hookBackboneAjax({ defaultOptions })
before making any Backbone requests (but after bringing in the Backbone.js js file).
You can pass it any default message options you would like to apply to your requests. You can also set those options as messenger in
your save and fetch calls.
Messenger().hookBackboneAjax({
errorMessage: 'Error syncing with the server',
retry: false
});
// Later on:
myModel.save({
errorMessage: 'Error saving contact'
});
Each message can have the following classes:
messenger-hidden (message): Applied when a message is hiddenmessenger-will-hide-after (message): Applied if the hideAfter option is not falsemessenger-will-hide-on-navigate (message): Applied if the hideOnNavigate option is not falsemessenger-clickable (message): Applied if a 'click' event is included in the events hashmessenger-message (message): Applied to all messagesmessenger-{type} (message): Applied based on the message's type (usually 'success', 'error', or 'info')message, alert, alert-{type} (message): Added for compatiblity with external CSSmessenger-retry-soon (message): Added when the next retry will occur in less than or equal to 10smessenger-retry-later (message): Added when the next retry will occur in greater than 10s (usually 5min)Every message lives in a slot, which is a li in the list of all the messages which have been created:
messenger-first (slot): Added when this slot is the first shown slot in the listmessenger-last (slot): Added when this slot is the last shown slot in the listmessenger-shown (slot): Added when this slot is visibleAll the slots are in a tray element:
messenger-empty (tray): Added when there are no visible messagesmessenger-theme-{theme} (tray): Added based on the passed in theme optionYou can have multiple messenger trays on the page at the same time. Manually create them using the jQuery method:
instance = $('.myContainer').messenger();
You can then pass your instance into the messenger methods:
Messenger({instance: instance}).post("My awesome message")
The build process requires nodejs and grunt-cli.
You can build the output files by running grunt.
The automated tests can be run by opening SpecRunner.html in a browser.