At UKOUG Techfest19 I gave a presentation with the same title as this article. The topic is about menus, dialogs, and popups. I created a sample app for the presentation that I promised to make available. You can download the app here[*]. The app uses the EMP and DEPT tables so make sure they are installed. You can install them from SQL Workshop > Utilities > Sample Datasets. The app is also using the Application Access Control feature so you will have to go to Shared Components > Application Access Control and assign roles to users before they can use the app. I only did this to demonstrate using authorization schemes in menus.
Even if you already know everything about menus, dialogs, and popups you may still want to check out the sample app because it contains DA action plug-ins Message Confirm and Message Alert that, as the names imply, use the
alert APIs rather than the native browser APIs, which the corresponding built-in actions still use. Another bonus is an updated version of the
showMe widget that I first introduced in my article Interactive Grid Tour App. There are list and region templates included that can be used to create a showMe tour.
[* Update. I noticed that on import the source setting on the page 12 chart region is lost. If this happens fix it by setting the source to local database table EMP.]
The slides should be available on the UKOUG site soon and also here. Slides never provide the full benefit of attending the presentation. I hope the sample app and the rest of this article fill in most of the holes. The sample app has a lot of descriptive text and code comments that you should read. On the About pages be sure to click the Details button. The following are the most important topics from the presentation.
Inline Dialog Region or Modal Dialog Page?
APEX supports 2 kinds of dialogs: inline dialog regions and modal dialog pages. The modal dialog page feature is more obvious and commonly used. Here are some guidelines on when to use each kind of dialog. These criteria can be in conflict and you will have to decide what is most important for a given case.
Use a modal page when you need submit processing and declarative validation. This also gives you the convenience of using a URL to open the dialog page. It is easier to open a modal page from multiple other pages but it is possible to do it with an inline region dialog as well by putting the inline region in the global page. Inline region dialogs often refresh the content when they open. If the region doesn’t support refresh, for example the tree region, then a dialog page may be your only option.
Use an inline dialog page when speed is of the utmost importance. For example a dialog that the user is likely to open many times should open quickly. Because inline dialogs are part of the page they open instantaneously. Another nice thing is that because the inline dialog is not created each time it opens, the dialog content remains the same unless you change it. If you have a small amount of data to deal with then an inline region can be easier. If you want non-modal behavior then inline dialogs are the way to go.
See also 3 Reasons to use Inline Dialogs by Matt Mulvaney.
Think of dialogs as functions
A modal dialog is the UI equivalent of a function. Properly designed it is a little bit of UI that can be reused from various places.
The page is the caller and the dialog is the function being called. Opening a dialog is like calling a function. When the user dismisses a dialog it is like a function returning. You may object and say that a function call is synchronous whereas opening and closing a dialog happen at two different times. But a function call is only synchronous in its thread. Even in languages that are single threaded the CPU can be doing other things during the function execution. The “calling” of the dialog happens in a single logical thread running in the user’s mind. Imagine they are executing the main page then open the dialog, deal with that, think about what to have for lunch, then go back to the dialog, work some more and then close it. You can imagine one logical thread even with interruptions to think about lunch.
Why bother with this metaphor? Because it helps us to follow good design practices. When you create a function you should think about reuse. If the function makes use of global state then it limits how it can be reused. For example if a function uses a global variable then you cant reliably use that function from another page because the global variable may not exist. In addition you have reduced the understandability and increased the maintenance cost of the code. There should be a nice clean interface between the function and its callers. Similarly when you create a dialog you should be thinking about reuse even if right now you can only foresee using it in one place. A dialog like a function should know nothing about its callers; when or where it is called from. And the main page should not have any access to the dialog internals. It should not reach into the dialog to manipulate it. Breaking these rules results in tight coupling between the page and the dialog reducing reusability and increasing maintenance. What the dialog needs should be passed into it and it should return what the caller may need from it.
You don’t have to follow this advice but at least consider it. Creating a clean interface around a dialog can take a little extra work but could be well worth the effort. The sample app has an example of this for inline dialogs and I wrote about how to do this for modal pages before.
Popups are not menus or tooltips
Popups look a little like tooltips but they are different in a few important ways. Popups typically open in response to clicking a button and are more likely to have content the user can interact with whereas tooltips display simple text and open on mouse hover or focus.
A popup can look similar to a menu but don’t use a popup when you should use a menu. Use a menu when the main purpose is navigation or one time commands or settings. A menu is better because:
- You don’t need a dynamic action to open it; use a declarative menu button.
- It automatically opens under the menu button.
- It is semantically more correct so better for accessibility because it has all the proper menu roles and states.
- Keyboard navigation is already supported.
- If you need a particular look it is better to use a custom content menu.
Declarative vs discoverable
One reason I picked this topic to present, other than I know a lot about menus, dialogs, and popups, is that I believe they are under utilized APEX features. These are useful controls to include in APEX apps and I want to make sure people know how to include them.
I think a big reason they are under utilized is that people don’t even know they exist in APEX. They don’t directly fit into the page, region, item, button entity model of APEX.
When you look at the layout gallery in page designer there is no menu or dialog or popup. You could reasonably conclude that they are not supported in APEX. This failing is on us and currently we have to rely on educating developers on how to find this functionality.
The key is in understanding that regions are made up of 2 parts. The region type and the template. The region type is the main functionality of the region such as a calendar or chart. The template is the markup around it with placeholders for buttons, items and sub regions.
The key realization is that templates can have behavior as well. There are many examples including tabs, carousel, and collapsible. So while menus, and inline dialogs and popups are declarative they are not easily discoverable. You need to somehow know that:
- A Menu is a List Region + Menu Popup List Template
- A Dialog is Any Region + Inline Dialog Region Template
- A Popup is Any Region + Inline Popup Region Template
Nothing stops you from making strange combinations (e.g. IG in a carousel container template).
Another example is the “menu button”. It is just a normal APEX button but you need to know about special values for some attributes that turn it into a menu button. It is still declarative in that you are using declarative attributes like CSS Classes and Custom Attributes but you need to know the special values “js-menuButton” and “data-menu” respectively.
I hope you find this information and the new sample app helpful.