Friday, November 4, 2016

Handling Dialog Cancel Event

If you ever had to handle a modal dialog close to trigger some action on the parent page, you probably used a dynamic action using the "Dialog Closed" event.

When closing a modal dialog there are two ways to do it.
  1. Close
    • Using an after submit process of type "Close Dialog";
    • Using a dynamic action with a "Close Dialog" action;
    • Branching to a page that has a "Normal" page mode.
  2. Cancel
    • Using a dynamic action with a "Cancel Dialog" action;
    • Clicking on the top right "X" icon/button.

When using a branch to close the modal dialog, the modal dialog will close then it's parent will branch to the specified page.

Except when using the branch method, when you close the modal dialog, Apex will trigger a "Dialog Close" event. Then, on the parent page, you will be able to handle it using a dynamic action "Dialog Closed" event.
The thing is that the cancel methods will not trigger any event on the parent page. So, by default, you won't be able to handle the dialog close when it was cancelled.

One way to have both the close and cancel method trigger an even on the parent page would be to override the dialog close event (Apex is using jQuery's  UI Dialog Widget).

So what we will do is this.

You will need to define the following JavaScript function (either on the parent pages, on page 0 or in your JavaScript global library file)
function customEvent(event, data){
    apex.event.trigger(document, event, data);
}

Then, under the modal dialog page attributes, in the dialog section, set the "Attributes" to:
close: function() { customEvent('customDialogClose', {modalPageId: 'MODAL_CLOSE_FIXED'});}

What this will do is that it will trigger (on the parent page) the event "customDialogClose".
The second parameter is a data attribute that could be used to differentiate modals between each other. It can can be useful if you are calling more than one on the parent page or if you want to send data back to the parent page.

Finally, in your parent page you can define a custom dynamic action as follow:
Event: Custom
Custom Event: customDialogClose
Selection Type: JavaScript Expression
JavaScript Expression: document

One thing to note is that the default close event will still be triggered when using the close method.

You can have a look at my Demo Application

6 comments:

  1. I don't recommend putting code in modal dialog page attribute. Why not use the already existing jQuery UI dialogclose event?
    Different dialogs can be distinguished by a css class you give it. The hard part is distinguishing a cancel from a close.

    ReplyDelete
    Replies
    1. The page "Attributes" attribute is extending the current jQuery UI dialogclose event. The modal dialog is built on top of jQuery UI Dialog. It's doing the same as if you used
      $( ".selector" ).dialog({
      close: function( event, ui ) {}
      });

      Both Close and Cancel DA are triggering the close modal event of the jQuery Dialog. The difference is that only the Close DA (or process) is then triggering the "Apex Modal Closed" event.

      From what I could find, there was no way to differentiate the Close from the Cancel.

      Let me know if I missed anything

      Delete
  2. Hi, why we cannot change behaviour of "Clicking on the top right "X" icon/button" with help of modal_dialog template section called "Dialog Cancel Code"?

    ReplyDelete
    Replies
    1. Hello Vladimir
      The jQuery "Close" method will always be fired regardless of what's triggered (close or cancel).

      It's just that APEX handles its internal event only and that only the close event is triggered.

      But yes, you could change the "Dialog Cancel Code". But to do so, you would need to either unsubscribe from the UT or to copy the template. Avoid unsubscribing from UT as much as possible.

      Regards
      Max

      Delete
    2. Hi Max, thanks to your APP I figure out how it works, I have a question now, how can I use the para 'data' in the dynamic action?

      Delete
  3. Thank you Maxime. This looks neat and clean way to define and handle custom events. I have to use this with version 19.1 as well as I hope there is no build-in way to handle dialog cancel event. Your solution works great from 2016 :-). Cheers.

    ReplyDelete