APEX

Closing dialogs by going back

published on

As developers, we are responsible for a lot of things when building an application. In addition to the actual business logic, the application must also look good and, above all, it must feel good. By feel, I mean the flow and the ease with which the application is operated. APEX already offers a lot of possibilities out of the box. Those possibilities have to be placed consciously and may be enriched with "LowCode", too, of course.

One point that I think needs to be adjusted is the way you act with modal dialogs. Especially when using a mobile, exactly one point always catches my eye. And that is navigating back from a modal dialog. The user, especially in case of Android-devices, is used to navigate back from a view by means of back-button. Precisely because APEX is responsive, many apps are also used on mobile devices. But if you want to navigate back, you will be navigated back to the previous parent page. That is not nice.

Fortunately, browsers provide us with an API to help us with this issue. With window.history.pushState we can add an entry to the browser's navigation stack and let the popstate event of the window object inform us that the user pressed the back button or that the history.back() event was triggered.

That is, whenever a ModalDialog opens, we put a new entry in the browser's history. When the back navigation event occurs, we close the ModalDialog. When closing ModalDialog manually, we will go back one step in history.

What does the whole thing look like in APEX. Calling page resp. global page needs following 3 methods.

// triggered when closing modal dialog
function customOnCloseEvent(event, data){
  hideModal();

  if (history.state == 'popup-open')  {
     window.history.back();
  }
}

// triggered on load of the modal dialog
function registerModal(pPageID) {
 window.history.pushState('popup-open', null, '');
 
 apex.jQuery(window).on('popstate', hideModal);    
}

// called when history.back() is triggered
function hideModal() {
  // close modal
  if (apex.jQuery('.ui-dialog-content > iframe')[0]) {
     apex.jQuery('.ui-dialog-content > iframe')[0]
				.contentWindow.apex.navigation.dialog.cancel(true);
  }

  // unregister function call 
  apex.jQuery(window).off('popstate', hideModal);
}

In addition, we register the method customDialogClose, which should always be triggered when a dialog is closed.

close: function() { customOnCloseEvent('customDialogClose', {modalPageId: 5});}

When loading the page, the following function must be called:

window.parent.registerModal('5');

That's it.