I have been working on a number of projects for my customers and recently, dialogs have taken front and center stage. The Office.context.ui Dialogs are powerful, albeit a tad confusing and the documentation suffers from a few easily missed points. Here is the documentation:
But in this post, I hope to explain everything I have learned. To start off with here is the code to issue the dialog:
Office.context.ui.displayDialogAsync('https://localhost:3000/function-file/dialog.html', { height: 20, width: 30, displayInIframe: true }, function (asyncResult) { dialog = asyncResult.value; // callbacks from the parent dialog.addEventHandler(Office.EventType.DialogEventReceived, processMessage); dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage); });
What this dialog does is opens as a modal form in a frame over the application (in Office Web Apps). It looks like this:
As you can see the dialog is modal. But what is really important are the two event handlers you need to register to be able to get back to your code:
dialog.addEventHandler(Office.EventType.DialogEventReceived, processMessage); dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
The first one is an event receiver and really this is the event handler for errors, such as being unable to open the dialog or, most importantly, the user closed the dialog by clicking the (X) in the upper right of the dialog. There are a series errors you can catch, but specifically, the dialog cancel is this:
12006 | The dialog box was closed, usually because the user chooses the X button. |
The second one is a handler for messages coming from the dialog. These messages can be anything, but is usually a string or a JSON string. You can send a message from the dialog like this:
Office.context.ui.messageParent('{message}');
When the dialog issues a message using the code above, the function defined in the event handler is called. For example, if the user clicks an OK button or Submit button, you can pass the stringified values from the form back to the callback function. From there the dialog actually remains open until the caller issues a close, like this:
// close the dialog dialog.close();
In the example above where I make the displayDialogAsync call, you will see I defined the SAME callback function for both dialog events. I did this because the results can be parsed by the same function. Here is what my function look like:
function processMessage(arg) { // close the dialog dialog.close(); // procress the result if(arg.error == 12006) { // user clicked the (X) on the dialog sendEvent.completed({ allowEvent: false }); } else { if(arg.message=="Yes") { // user clicked yes sendEvent.completed({ allowEvent: true }); } else { // user clicked no sendEvent.completed({ allowEvent: false }); } } }
My previous blog post references all the code for the dialog:
[…] working hard on my OfficeJS.Dialogs library and just published version 1.0.5. You can get it from NPM and GitHub. See my previous post for more information on how to do […]
Hi David, do you know if it’s possible to use Office.context.mailbox in the dialog window? I want to call either Outlook rest api or EWS, but both of them require Office.context.mailbox for authentication, (e.g. Office.context.mailbox.getCallbackTokenAsync()).
If that’s not possible/recommended, how would you advise to pass email data to the dialog?
Thanks!
You should be able to use Office.context.mailbox as long as you did an Office.initialize. Is there a specific error or problem you are getting?
However, I have found that it is unnecessary to perform mailbox level work in a dialog. If you collect the information you need before you enter the dialog, you can store it in JSON format in an browser session storage item or if you need to perform an action after a user interaction, you can use MessageParent to send a message back to your code in the function-file or taskpane in order to perform the work and return the data to the dialog, again with session storage. If you do not perform a dialog.close() on the reciept of the message, the dialog will remain open. My OfficeJS.dialogs library has some examples of how to perform two-way communication between your taskpane/function-file and the dialog.
Thanks David. I’m using browser’s local storage for now, I guess that’s you were referring to as well. When I was trying to get hold of Office.context.mailbox in the dialog, mailbox was “undefined”. It must be one of the limitation of dialog api.