Difference between revisions of "AppSuite:Writing a notification area plugin"

(Adding and removing notifications)
(Adding and removing notifications)
Line 176: Line 176:
  
 
<pre language="javascript">
 
<pre language="javascript">
define('plugins/notifications/tutorial/register', [
 
    'io.ox/core/extensions',
 
    'io.ox/core/notifications/subview'
 
], function (ext, Subview) {
 
 
    'use strict';
 
  
 
     var counter = 0;
 
     var counter = 0;
Line 210: Line 204:
 
     });
 
     });
  
    ext.point('io.ox/core/notifications/register').extend({
 
        id: 'tutorialplugin',
 
        index: 1000,
 
        register: function () {
 
            var options = {
 
                    id: 'io.ox/tutorialplugin',
 
                    title: 'Test Notifications',
 
                    extensionPoints: {
 
                        item: 'io.ox/core/notifications/tutorial/item',
 
                        footer: 'io.ox/core/notifications/tutorial/footer'
 
                    },
 
                    autoOpen: true,
 
                    showHideAllButton: true,
 
                    hideAllLabel: 'Hide all tutorial notifications'
 
                },
 
                subview  = new Subview(options);
 
 
            subview.resetNotifications({ id: 'myNotification' + counter, text: 'I am notification number ' + counter });
 
            counter++;
 
        }
 
    });
 
 
    return true;
 
});
 
 
</pre>
 
</pre>
  
 
You should see Something like this in your browser:
 
You should see Something like this in your browser:

Revision as of 12:43, 10 September 2015

Writing a plugin for the notification area

Abstract: This article is a step by step tutorial to build your own notification plugin. These plugins can be used for various purposes, for example reminding the user of something or showing him new invitations.

Basic Notification

First let's start with showing the most basic notification plugin you can write. Create a file named register.js at plugins/notifications/tutorial.

This code doesn't have api suppport or other things but adds a hello world notification:

define('plugins/notifications/tutorial/register', [
    'io.ox/core/extensions',
    'io.ox/core/notifications/subview'
], function (ext, Subview) {

    'use strict';

    ext.point('io.ox/core/notifications/tutorial/item').extend({
        draw: function () {
            this.append( $('<span>').text('hello world'));
        }
    });

    ext.point('io.ox/core/notifications/register').extend({
        id: 'tutorialplugin',
        index: 1000,
        register: function () {
            var options = {
                    id: 'io.ox/tutorialplugin',
                    title: 'Test Notifications',
                    extensionPoints: {
                        item: 'io.ox/core/notifications/tutorial/item'
                    }
                },
                subview  = new Subview(options);

            subview.resetNotifications({ id: 'myNotification1' });
        }
    });

    return true;
});

This code extends two extension points: io.ox/core/notifications/tutorial/item and io.ox/core/notifications/register

We use io.ox/core/notifications/tutorial/item to draw our notification items. Here it's a simple hello world text.

io.ox/core/notifications/register is used by the notification area to load the different plugins. Those plugins are implemented as subviews of the main notification area. The index determines the order of the different subviews. We define some options for our view here:

  • id: the internalId for our subview
  • title: the text in the header of our subview
  • extensionPoints: here we tell the subview which extensionpoints to use when drawing our notifications. For now we only use io.ox/core/notifications/tutorial/item to draw our items.

More options will be explained later on.

Now we create our view and add notification to it:

subview  = new Subview(options);

subview.resetNotifications({ id: 'myNotification1' });

Adding a manifest

Now we need to add a manifest.json file at plugins/notifications/tutorial with the following contents:

{
    "namespace": "io.ox/core/notifications",
    "requires": ""
}

This manifest makes sure our code is loaded. You can also define capabilities like webmail here, if your notifications require specific capabilities to be enabled. They only show up if a user has these capabilities.

Testing our notification

Now it's time to test our notification. Build the UI and add &customManifests=true to the url, because our manifest is only present locally.

After reloading you should see something like this:

BasicNotification.png

Expanding our Plugin

We can add more functionality to our plugin by using the options when creating the subview. Here are some more:

  • showHideAllButton: Is used to show a hide all button for your subview. This button hides all current notifications of your subview. Default is false
  • hideAllLabel: Is the aria-label for the hide all button that is used by screen readers. Default is empty string
  • showHideSingleButton: Is used to show a hide button for your notifications. This button hides a single notification of your subview. Default is true
  • max: The maximum number of displayed notifications in this subview. The actual collection may contain more. Setting this to null will show all notifications. Default is 10
  • autoOpen: Used to open the notification area, if there is a new notification for your plugin. You may want to tie this to a user setting. Default is false
  • extensionPoints: This is an object where you can define extension points used when drawing your subview. Possible points are:
    • main: The main extension point. If you overwrite this you can draw the subview completely by hand. If you keep the default value, this extension point invokes the header, item and footer extension points for you.
    • header: The extension point for your subview header. The default extension point uses the supplied title attribute and draws the hideall button if enabled.
    • item: The extension point for a single notifications. This extension point has no default value and must be provided by the plugin when creating the subview. In our example this was io.ox/core/notifications/tutorial/item.
    • footer: The extension point for the footer. If your subview should have a footer you can provide an extension point for this. There is no default extension point and it's entirely optional.

Let's add a footer to our plugin, make it autopen, show the hide all button. The code looks like this:

define('plugins/notifications/tutorial/register', [
    'io.ox/core/extensions',
    'io.ox/core/notifications/subview'
], function (ext, Subview) {

    'use strict';

    ext.point('io.ox/core/notifications/tutorial/footer').extend({
        draw: function () {
            this.append($('<button class="btn">').text('click me')
                .on('click', function () {
                    alert('footer button was clicked');
                }));
        }
    });

    ext.point('io.ox/core/notifications/tutorial/item').extend({
        draw: function () {
            this.append($('<span>').text('hello world'));
        }
    });

    ext.point('io.ox/core/notifications/register').extend({
        id: 'tutorialplugin',
        index: 1000,
        register: function () {
            var options = {
                    id: 'io.ox/tutorialplugin',
                    title: 'Test Notifications',
                    extensionPoints: {
                        item: 'io.ox/core/notifications/tutorial/item',
                        footer: 'io.ox/core/notifications/tutorial/footer'
                    },
                    autoOpen: true,
                    showHideAllButton: true,
                    hideAllLabel: 'Hide all tutorial notifications'
                },
                subview  = new Subview(options);

            subview.resetNotifications({ id: 'myNotification1' });
        }
    });

    return true;
});

And it should look like this:

NotificationWithFooter.png

Adding and removing notifications

Now we need to talk about how notifications are added and removed. Our subview has a backbone collection which stores all it's notifications. The notifications need an id so the collection can avoid duplicates and handle hiding correctly. Our example notifications id was myNotification1. This collection can be changed by using 3 methods:

  • addNotifications: Adds notifications to the collection. Only adds notifications which have a new id. Has 2 parameters:
    • items: Is a single object or an array of objects to be added as new notifications
    • silent: Is a boolean that can be set to true if the new notifications should be added silently. This prevents immediate redrawing.
  • removeNotifications: Removes notifications from the collection. Has items and silent parameter, like addNotifications.
  • resetNotifications: Resets the collection. This throws away all notifications in the collection and fills it with the provided new ones. Can also be used to clear the collection, when an empty array is provided. Again has items and silent parameter, like addNotifications.

Let's expand our example by adding buttons to the footer to add notifications and reset them. Let's also add a button to remove a notification and show some data in our notifications.

The code looks like this:


    var counter = 0;

    ext.point('io.ox/core/notifications/tutorial/footer').extend({
        draw: function (baton) {
            this.append($('<button class="btn">').text('reset notifications')
                .on('click', function () {
                    counter = 0;
                    baton.view.resetNotifications({ id: 'myNotification' + counter, text: 'I am notification number ' + counter });
                    counter++;
                }),
                $('<button class="btn">').text('add notifications')
                .on('click', function () {
                    baton.view.addNotifications({ id: 'myNotification' + counter, text: 'I am notification number ' + counter });
                    counter++;
                }));
        }
    });

    ext.point('io.ox/core/notifications/tutorial/item').extend({
        draw: function (baton) {
            this.append($('<div>').text(baton.model.get('text')),
                $('<button class="btn">').text('remove notification').on('click', function () {
                    baton.view.removeNotifications(baton.model);
                }));
        }
    });

You should see Something like this in your browser: