8. Dialogs

Dialogs are used throughout the WebApp. Dialogs are an important part in the application. When you are creating an email, appointment, a contact or when opening the address book: the contents will always be shown in a dialog.

The Zarafa.core.ui.ContentPanel has a couple of generic subclasses that might help in managing MAPI objects (objects that contain information on e.g. e-mail, appointments, etc.). There are two basic types of dialogs in WebApp: Zarafa.core.ui.RecordContentPanel and Zarafa.core.ui.ContentPanel. Each Dialog must inherit from either one to benefit from any automatically added user interface elements and styling.

Usually, you would use Zarafa.core.ui.ContentPanel. If you want to handle MAPI records, then see sections Dealing with MAPI records and Stores and RecordFactory for more background information.

8.1. Events

For plugins, it is possible to detect when a Dialog is about to be displayed to the user, allowing it to hook into further events of the Dialog itself, or any of its components. To do this, the plugin must listen to the createdialog event from the Zarafa.core.data.ContentPanelMgr singleton object. This event will pass the dialog that is being displayed as argument. Note that the event is called before the dialog is rendered. The DialogMgr will inform the plugin that the dialog has disapeared using the destroydialog event.

8.2. Example

The following code snippet shows how we can create our own custom dialog. This is just the definition of the dialog and its contents, it does not yet make it available to WebApp yet.

Ext.namespace('Dialogs.dialogsexample.dialogs');

/**
 * @class Dialogs.dialogsexample.dialogs.SimpleDialog
 * @extends Zarafa.core.ui.ContentPanel
 *
 * The simple dialog which contains Ext.panel.
 * @xtype simpledialog
 */
Dialogs.dialogsexample.dialogs.SimpleDialog = Ext.extend(Zarafa.core.ui.ContentPanel, {
        /**
         * @constructor
         * @param config Configuration structure
         */
        constructor : function(config)
        {
                config = config || {};
                Ext.applyIf(config, {
                        defaultTitle            : _('Simple Dialog'),
                        alwaysUseDefaultTitle   : true,
                        width                   : 340,
                        height                  : 200,
                        //Add panel
                        items                   : [
                        {
                                xtype : 'panel'
                        }
                        ]
                });

        //Call superclass constructor
        Dialogs.dialogsexample.dialogs.SimpleDialog.superclass.constructor.call(this, config);
        }
});

// Register the dialog xtype
Zarafa.core.ui.ContentPanel.register(Dialogs.dialogsexample.dialogs.SimpleDialog, 'simpledialog');

You can see that to create a custom dialog, we need to extend Zarafa.core.ui.ContentPanel and call the superclass constructor inside the dialog constructor. Finally, the last step that should be done is to register this dialog with a custom xtype:

Zarafa.core.ui.ContentPanel.register(Dialogs.dialogsexample.dialogs.SimpleDialog, 'simpledialog');

And that’s it! In the items list, you can put the content that you wish.

It can be any subclass of Ext.Component. Now we can use our dialog from WebApp, just run the following from the Javascript console while WebApp is loaded:

Dialogs.dialogsexample.dialogs.SimpleDialog.create({
        title : _('My Custom Dialog')
});

This piece of code will create an instance and show the dialog on screen.

8.3. Dealing with MAPI records

When working with MAPIRecord instances, it is useful to use the Zarafa.core.ui.RecordDialog, because it has better support for managing MAPIRecords and has extra functionality for saving the record. For Messages (e.g. Mail and Meeting Requests), we have the Zarafa.core.ui.MessageDialog which extends the RecordDialog functionality to support sending the message to all recipients.

A Dialog that displays the contents of an IPMRecord must always inherit from RecordDialog. This dialog accepts the record configuration option which will be opened by default, otherwise it is possible to set the displayed IPMRecord through the setRecord function on this dialog. Using the RecordDialog, the dialog will automatically hook into the IPMStoreManager to listen for update events regarding the IPMRecord which is opened by the dialog. Also, with the setrecord and updaterecord events, the dialog can inform all components within the dialog about record changes.

A Dialog that is used for creating or editing an IPMRecord must always inherit from EditRecordDialog. EditRecordDialog is a subclass of RecordDialog, and therefore offers the same features.

Additionally, the EditRecordDialog automatically places all edited IPMRecords into the ShadowStore. For further explanation of the shadow store and why it is relevant, see IPM Stores and ShadowStore.

See “RecordDialog UML diagram” for how they relate to each other.

RecordDialog UML diagram

RecordDialog UML diagram

8.3.1. Displaying a record

When adding a Panel to the RecordDialog (or EditRecordDialog), it is recommended to extend the RecordDialogPanel. This Panel will take the RecordDialog update features into account and automatically updates the Panel when the RecordDialog signals a change in the IPMRecord for this Dialog. Any subclass of RecordDialogPanel is required only to implement the function update(record) which will be called when the Record is updated.

The constructor of the subclass does not receive a record field; furthermore, the constructor must assure that any components which display particular fields of the IPMRecord are initialized to display a default value (i.e. undefined or an empty string). When the Dialog is rendered, the update(record) function will be used to set the IPMRecord for the first time.

Both the RecordDialog and EditRecordDialog offer default buttons for the Toolbar for saving and deleting the IPMRecord which is contained in the Dialog.