Skip to content

Commit

Permalink
[#2648] Add a ckan.notify() function
Browse files Browse the repository at this point in the history
This can be used to display alert messages to the user and is made available
to modules via the sandbox.notify() method.

Usage:

  sandbox.notify('An error occurred', 'unable to download file');
  • Loading branch information
aron committed Jul 11, 2012
1 parent 4bf1fe0 commit e28011e
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
71 changes: 71 additions & 0 deletions ckan/public/base/javascript/notify.js
@@ -0,0 +1,71 @@
(function (ckan, jQuery) {

/* Displays a global notification banner on the screen. Takes a title
* and optional message and type arguments.
*
* title - The main message string.
* message - Additional information.
* type - A type to apply to the message (default: error)
*
* Examples
*
* ckan.notify('An error occurred', 'etc');
* ckan.notify('Success', 'user updated', 'success');
*
* var alert = ckan.notify('An error occurred');
* alert.on('closed', function () {
* // Do something.
* });
*
* Returns the error element.
*/
function notify(title, message, type) {
var alert = notify.initialize(notify.create(title, message, type));
notify.el.append(alert);
}

// Grab the flash message container.
notify.el = jQuery('.flash-messages', document.body);

/* Creates a new message element.
*
* title - The main message string.
* message - Additional information.
* type - A type to apply to the message (default: error)
*
* Returns the element.
*/
notify.create = function (title, message, type) {
var alert = jQuery('<div class="alert fade in"><strong></strong> <span></span></div>');
alert.addClass('alert-' + (type || 'error'));
alert.find('strong').text(title);
alert.find('span').text(message);
return alert;
};

/* Adds a close button and initializes the Bootstrap alert plugin.
*
* element - An element to initialize.
*
* Returns the element.
*/
notify.initialize = function (element) {
element = element instanceof jQuery ? element : jQuery(element);
return element.append(jQuery('<a class="close" href="#">&times;</a>')).alert();
};

// Initialize any alerts already on the page.
notify.el.find('.alert').each(function () {
notify.initialize(this);
});

// Watch for close clicks and remove the alert.
notify.el.on('click', '.close', function () {
jQuery(this).parent().alert('close');
});

// Export the objects.
ckan.notify = notify;
ckan.sandbox.extend({notify: notify});

})(this.ckan, this.jQuery);
4 changes: 4 additions & 0 deletions ckan/public/base/test/index.html
Expand Up @@ -23,6 +23,8 @@

<!-- Source -->
<script src="../javascript/vendor/jquery.js"></script>
<script src="../vendor/bootstrap/js/bootstrap-transition.js"></script>
<script src="../vendor/bootstrap/js/bootstrap-alert.js"></script>
<script src="../javascript/plugins/jquery.inherit.js"></script>
<script src="../javascript/plugins/jquery.url-helpers.js"></script>
<script src="../javascript/plugins/jquery.slug.js"></script>
Expand All @@ -31,6 +33,7 @@
<script src="../javascript/module.js"></script>
<script src="../javascript/pubsub.js"></script>
<script src="../javascript/client.js"></script>
<script src="../javascript/notify.js"></script>
<script src="../javascript/i18n.js"></script>

<!-- Suite -->
Expand All @@ -41,6 +44,7 @@
<script src="./spec/sandbox.spec.js"></script>
<script src="./spec/module.spec.js"></script>
<script src="./spec/client.spec.js"></script>
<script src="./spec/notify.spec.js"></script>

<script>
beforeEach(function () {
Expand Down
45 changes: 45 additions & 0 deletions ckan/public/base/test/spec/notify.spec.js
@@ -0,0 +1,45 @@
describe('ckan.notify()', function () {
beforeEach(function () {
this.element = jQuery('<div />');
this.fixture.append(this.element);

ckan.notify.el = this.element;
});

it('should append a notification to the element', function () {
ckan.notify('test');
assert.equal(this.element.children().length, 1, 'should be one child');
ckan.notify('test');
assert.equal(this.element.children().length, 2, 'should be two children');
});

it('should append a notification title', function () {
ckan.notify('test');
assert.equal(this.element.find('strong').text(), 'test');
});

it('should append a notification body', function () {
ckan.notify('test', 'this is a message');
assert.equal(this.element.find('span').text(), 'this is a message');
});

it('should escape all content', function () {
ckan.notify('<script>', '<script>');
assert.equal(this.element.find('strong').html(), '&lt;script&gt;');
assert.equal(this.element.find('span').html(), '&lt;script&gt;');
});

it('should default the class to "alert-error"', function () {
ckan.notify('test');
assert.ok(this.element.find('.alert').hasClass('alert-error'));
});

it('should allow a type to be provided', function () {
ckan.notify('test', '', 'info');
assert.ok(this.element.find('.alert').hasClass('alert-info'));
});

it('should add itself to the ckan.sandbox()', function () {
assert.equal(ckan.sandbox().notify, ckan.notify);
});
});

0 comments on commit e28011e

Please sign in to comment.