Sunday, 5 July 2015

Apex 5.0 - Getting Down With Dialogs (Part 1)

A part of any modern day web application is the use of dialogs. With the release of Apex 5.0, the development team has obviously put a great deal of work into this functionality and made it an integral part of Apex. Through the use of JQuery UI, the team has given us some feature-rich components and processes to use to support our need for dialogs.

In their simplest terms, dialogs are interactive modal  popups that can be used to give additional information to the user, assist them in processing selected steps, or guide them through a wizard of nested steps. They offer the user the sense of "staying" where they are and not having to navigate around to accomplish a task. Dialogs are immediate, dramatic and captivating.

In previous versions of Apex, we had to use plug-ins or write considerable javascript to build these kind of dialogs into our applications. Now, with Apex 5.0, the full power of dialogs is rigt at our fingertips.

There are several types of dialogs available in Apex 5.0. In this first post in the series, I will discuss only one of them - the inline dialog.

Inline dialogs are really just regions on a page that function like a modal "popup" dialog. They are distinct from their more powerful cousin, the modal dialog page, in that they are simply a region and not a page. This, while it may seem obvious, is a key point. As a region on an existing page, the inline dialog does not need all of overhead involved in page rendering and processing. The region is in fact rendered as part of its containing page and therefore can be displayed very quickly. This lightweight "here I am" power of the inline dislog is also a bit of a weakness. As a region on a larger page, it lacks the validation and processing power of a separate page and is therefore not really suited to complex operations.

Before we go into the details of how to create an inline dislog, we ought to understand what in fact it will do.


 As you can see from the above image, an inline dialog looks and feels much like a modal page. When the dialog is opened, the launching page is dimmed to highlight the modal region. The dialog awaits the users interaction before continuing and the underlying parent page is "frozen". Much like a modal page, it can have buttons to invoke actions, but it is important to understand that the whole page, not just the modal region, will be submitted when the button is clicked. More about that later.

It may help if I take a moment to explain my specific use of the inline dialog here. My application tends to be very dynamic. I am always adding new functionality and need a way of highlighting the new features to users. So, what I have developed is a page messaging franework. I have a database table where I store the messages that I want to display referenced by page number. When a user launches a page in the application, a process checks to see if there is a message to be displayed to the user for that page. If the user has not viewed the message before, the inline dialog is displayed with the message and title from the database table. Once the user clicks the "Got It" button, I record that the user has viewed this message and it will not be displayed for the user again. The framework allows me to set messages for any page in my application in order to help users find and use new features.

So, how do we create the inline dialog? It is really pretty simple. Create a new region on the page and set the region template to "inline dialog."



In my case, because I need the title and content to by dynamic, I have two hidden page items that I reference for both the region title and the content.

Once you have selected the region template of "inline dialog, you can open the Template Options where there are a number of settings to further control and appearance of the region.


Once you have the region the way you want it, it is time to trigger the display of the modal region. You need to determine under what circumstances the region will be displayed. Here, I want the region to be displayed on the loading of the page if there is a message to be displayed and the user has not viewed the message before. As I mentioned earlier, I have hidden page items for the title and content of the inline dialog message. These page items only get values assigned to them if there is a message to display for that specific page and if the user has not yet viewed the message. This then gives a mechanism for displaying the dialog. If the hidden items are not null, then I want to display the dialog. So, I have an "on change" dynamic action that references the hidden page item and fires if the item is not null:


Then, as part of my dynamic action, I use a true action of "Execute Javascript Code" to open the dialog:


Notice that I pass the static id for the region to the openModal function. And that's it! The inline dialog will be displayed. Of course, your triggering action may be quite different, but you get the idea.

Let's return to my earlier point about the entire page being submitted. An inline dialog region is different from a "modal page" in that it is simply a component of the parent page. Consider my "Got It" button that is part of my dialog region. The button has the behaviour of "Submit Page." When it is clicked, because the inline dialog is part of the parent page, the entire page will be submitted with all of its items etc. Therefore, it is important that you control the processing and branching based only on the single button being clicked. There are several ways to do this, but the most common would be to use the "When button pressed" condition processes and branches.

There are some other important issues associated with the fact that the inline dialog is simply a region of the parent page:

1.  It will display very quickly as it is rendered with the parent page.
2.  Unlike a modal page, it shares its processing with the parent page.
3.  It is best suited for static content and limited user interaction.

There are lots of ways you can effectively use inline dialogs. You can use them for messages (as I hve), for alerts, confirmations or for quick popups that display additional information when the user opts to view it. They are very slick and can really contribute to a positive user experience.

Modal regions have been a part of Apex for quite a while. But now, with Apex 5 and the built-in use of JQuery UI, they are easier than ever and offer the developer a great deal of options of customization and control.

Add a comment to this blog and let me know how you are making use of inline dialogs. And watch for Part 2 in this series where I will discuss the more powerful and feature-rich modal dialog page.



9 comments:

  1. You did a great job of explaining this!
    One possibility is rather than have the got it button submit the page, have it send which message was acknowledged with AJAX. It could be a PL/SQL dynamic action or a JavaScript action using an apex.server API to call an application process.

    ReplyDelete
    Replies
    1. Hi John:

      Thanks so much for your feedback and thanks for the suggested alternative to submitting the enitre page. I'll give the AJAX approach a go - it is a great suggestion.

      Delete
  2. Trying to use your example, but modified slightly.. As a test I have a button on a page that calls a Dynamic Action. In the dynamic action I set two hidden page items (P225_MESSAGE_TITLE, P225_MESSAGE_TEXT). I am trying to use these items for the inline dialog region title and message to be displayed. However when the dialog is displayed they are BOTH NULL.

    Any suggestions?

    Thank you,

    Tony Miller
    texas.apex.developer@gmail.com
    Los Alamos, NM

    ReplyDelete
  3. can we open inline dialog using plsql..like
    if condition true then
    open modal dialog;
    else
    open another modal dialog;
    end if;

    ReplyDelete
    Replies
    1. Hi Santhosh,

      The most simple way:

      Create a hidden page item for example "PX_MY_ITEM";

      So, create a dynamic action Execute PL/SQL code and put this:
      DECLARE
      vCOUNT PLS_INTEGER := 0;

      BEGIN

      IF MYCONDITION THEN

      vCOUNT := 1;

      ELSIF MYCONDITION THEN

      vCOUNT := 2;

      ELSE

      vCOUNT := 0;

      END IF;

      :PX_MY_ITEM := vCOUNT;
      END;

      Create another DA type Execute Javascript and put this:

      if(parseFloat($v('PX_MY_ITEM'))==1)
      {
      openModal('modal1');
      } else if(parseFloat($v('PX_MY_ITEM'))==2)
      {
      openModal('modal2');
      }


      I hope this help

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. I keep having to come back to this article to remind myself of the openModal javascript function. It doesn't seem to be documented anywhere else! I'm surprised it isn't built in as a separate Dynamic Action option.

    ReplyDelete
  6. Have you sorted it out how to dynamically resize it depending on the size of the content? I can set a fix value, but if the content changes a bit, you get a big blank square with little content filling it. I would prefer to have something more automatic to it, than having to decide best size and set it each item I open a dialog.

    ReplyDelete
  7. Well, good information you have placed and useful too. Just now I saw your blog and it is nice and good.This information is stunning. I hope it will be very helpful for all. I don't have words to describe this blog. I simply want to say that absolutely very good post.
    Engineering Colleges, Mechanical Engineering Colleges in Chennai



    ReplyDelete