19 Using Dialogs in Your Application

This chapter describes how you can use ADF Controller and ADF task flows to create dialogs or, alternatively, how to use the ADF Faces dialog framework in an ADF application.

This chapter includes the following sections:

19.1 Introduction to Using Dialogs in Your Application

Use dialogs if you want to show information to end users in a secondary browser window external to the browser window that displays the end user's current page. For example, you want to display help information to end users to assist them with a task in the primary browser window or you want end users to select a value from a list of values. The help information example is a use case a modeless dialog is appropriate. A modeless dialog allows end users work in both the primary window and the dialog at the same time. For the use case where you want an end user to select a value, a modal dialog is more appropriate. A modal dialog prevents an end user accessing the page that invoked the dialog until they execute an action requested by the dialog (for example, select a value).

Use the ADF Faces dialog framework if you want to configure modeless dialogs for your end users. If you plan to configure modal dialogs for your end users, configure an ADF Controller bounded task flow to invoke one or more dialogs.

19.2 Running a Bounded Task Flow in a Modal Dialog

You can configure a bounded task flow to run in a modal dialog, retrieve input from an end user, and return to the view activity that called the bounded task flow with the retrieved input.

Figure 19-1 shows an example of the configuration required.

Figure 19-1 Task Flow Activities to Invoke a Modal Dialog

Task Flow Invoking a Modal Dialog

19.2.1 How to Run a Bounded Task Flow in a Modal Dialog

In an existing task flow, add a view activity and a task flow call activity to a bounded task flow. The view activity invokes a page where an end user can invoke an action that, in turn, invokes the bounded task flow to appear in a modal dialog.

To run a bounded task flow in a modal dialog box:

  1. In the diagram editor for the existing task flow, double-click the view activity to open the associated page.

  2. Select the UI component that the end user clicks at runtime to invoke the bounded task flow as a modal dialog box (for example, a commandButton component).

  3. In the Property Inspector, expand the Common section and set the action attribute to the control flow case to invoke the bounded task flow.

    For example, callTarget in Figure 19-1.

  4. Set the useWindow attribute to true to invoke the bounded task flow in a popup dialog.

  5. Return to the diagram editor for the existing task flow and select the task flow call activity.

  6. In the Property Inspector, expand the Behavior section and set the run-as-dialog attribute to true to run the bounded task flow as a dialog.

  7. For the display-type attribute, select external-window (the default value) if you want to render the dialog in an external browser window or inline-popup if you want to render the dialog in the same browser window.

19.2.2 How to Return a Value From a Modal Dialog

You can configure a bounded task flow that renders in a modal dialog to return a value to the view activity that invoked the bounded task flow when the end user dismisses the modal dialog. The returned value can, for example, be displayed in an input component on the page associated with the view activity.

You must configure the bounded task flow that is called by the task flow call activity to declare input and output parameters. For more information, see Section 16.3, "How to Pass Parameters to an ADF Bounded Task Flow".

You specify a method binding for a method with one argument (a return event) as the value for the returnListener attribute of the command component (for example, a commandButton component). The returnListener attribute sets this value in the input component on the page associated with the view activity. Specify a backing bean for the input component and set the input component's partialTrigger attribute to the ID of the command component.

You also need to specify:

  • A return value definition on the called bounded task flow to indicate where to take the return value from upon exit of the called bounded task flow.

  • Return values on the task flow call activity in the existing task flow to indicate where the existing task flow can find return values.

    For more information, see Section 16.5, "Specifying Return Values".

For more information about creating backing beans, input components, and command components, see the "Using Input Components and Defining Forms" chapter in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Before you begin:

Configure a bounded task flow to run in a modal dialog. For more information, see Section 19.2.1, "How to Run a Bounded Task Flow in a Modal Dialog".

To specify a return value:

  1. In the diagram editor for the existing task flow, select the task flow call activity.

  2. In the Property Inspector, expand the Behavior section and set the run-as-dialog attribute to true.

  3. Set the dialog-return-value to the name of the return value definition you specified for the target bounded task flow.

    For information about how to specify the return value definition on a bounded task flow, see Section 16.5, "Specifying Return Values".

  4. In the Application Navigator, double-click the page that launches the modal dialog.

  5. Select the input component on the page and, in the Property Inspector, expand the Behavior section to specify an EL expression for the partialTriggers attribute.

    The EL expression you specify identifies the command component, accepts the return value of the command component, and specifies a backing bean. For example, enter an EL expression with syntax similar to the following:

    #{pageFlowScope.backingBean.gotoModalDialog}

    Where gotoModalDialog identifies the command component.

  6. Select the command component and, in the Property Inspector, expand the Behavior section.

  7. In the Secondary Window, enter an EL expression that references a return listener method in the page's backing bean as a value for the returnListener attribute.

    The return listener method you specify processes the return event that is generated when an end user dismisses the modal dialog. Enter an EL expression with syntax similar to the following:

    #{pageBean.listenerMethod}

19.2.3 What You May Need to Know About Running a Bounded Task Flow in a Modal Dialog

A bounded task flow can run in an ADF region. The ADF region can be in an af:popup UI component.

You cannot specify dialog:syntax in navigation rules within the faces-config.xml file if your Fusion web application uses ADF Controller features such as task flows. However, you can use the dialog:syntax in the control flow rules that you specify in the adfc-config.xml file.

Example 19-1 shows an example of what you can specify in the adfc-config.xml file.

Example 19-1 adfc-config.xml file with dialog:syntax

<?xml version="1.0" encoding="windows-1252" ?> 
  <adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2" id="__1"> 
    <view id="view1"
        <page>/view1.jspx</page> 
    </view>
    <view id="dialog"> 
       <page>/dialog/untitled1.jspx</page> 
   </view> 
   <control-flow-rule> 
        <from-activity-id>test</from-activity-id> 
        <control-flow-case> 
          <from-outcome>dialog:test</from-outcome
          <to-activity-id>dialog</to-activity-id>
         </control-flow-case> 
</adfc-config>

19.3 Using the ADF Faces Dialog Framework

You can use the ADF Faces dialog framework to create modal and modeless dialogs in an application that does not use the ADF Controller and task flows. The dialog framework enables you to display a page or series of pages in a new browser window instead of displaying it in the same window (using the same view ID) as the current page. There may also be cases where you want to use a series of inline dialogs, that is, dialogs that are part of the parent page, but that have a flow of their own, but that do not use a separate view ID. This is important for applications that do not support popups such as, for example, applications that run on client devices or that use the Active Data Service described in Chapter 42, "Using the Active Data Service." Ordinarily, you would need to use JavaScript to open the dialog and manage the process. With the dialog framework, ADF Faces has made it easy to open a new browser window as well as manage dialogs and processes without using JavaScript.

Note:

If your application uses the Fusion technology stack with the ADF Controller, then you should use task flows to create dialogs launched in a separate window, or multiple dialog processes. For more information, see Section 19.2, "Running a Bounded Task Flow in a Modal Dialog".

Consider a simple application that requires users to log in to see their orders. Figure 19-2 shows the page flow for the application, which consists of five pages - login.jspx, orders.jspx, new_account.jspx, account_details.jspx, and error.jspx.

Figure 19-2 Page Flow of an External Dialog Sample Application

Page flow of a popup dialog sample application

When an existing user logs in successfully, the application displays the Orders page, which shows the user's orders, if any. When a user does not log in successfully, the Error page displays in a separate popup dialog window, as shown in Figure 19-3.

Figure 19-3 Error Page Popup

Error Page Popup

On the Error page there is a Cancel button. When the user clicks Cancel, the popup dialog closes and the application returns to the Login page and the original flow, as shown in Figure 19-4.

Figure 19-4 Login Page

Log in screen for username and password in a popup dialog

When a new user clicks the New User link on the Login page, the New Account page displays in a popup dialog in a new window, as shown in Figure 19-5.

Figure 19-5 New Account Page in a Separate Window

New account page in a popup dialog

After entering information such as first name and last name, the user then clicks the Details button to display the Account Details page in the same popup dialog, as shown in Figure 19-6. In the Account Details page, the user enters other information and confirms a password for the new login account. There are two buttons on the Account Details page - Cancel and Done.

Figure 19-6 Account Details Page in a Popup Dialog

account details page in a popup dialog

If the new user decides not to proceed with creating a new login account and clicks Cancel, the popup dialog closes and the application returns to the Login page. If the new user clicks Done, the popup dialog closes and the application returns to the Login page where the Username field is now populated with the user's first name, as shown in Figure 19-7. The new user can then proceed to enter the new password and log in successfully.

Figure 19-7 LogIn Page with Username Field Populated

login page with username defined

Note:

The dialog framework should not be used to have more than one dialog open at a time, or to launch dialogs that have a life span outside of the life span of the base page.

To make it easy to support dialog page flows in your applications, ADF Faces has built in the dialog functionality to action components (such as commandMenuItem and commandButton). For ADF Faces to know whether or not to open a page in a new flow from an action component, the following conditions must exist:

  • There must be a JSF navigation rule with an outcome that begins with dialog:.

  • The command component's action outcome must begin with dialog:.

  • The useWindow attribute on the command component must be true.

Note:

If the useWindow attribute is false, or if you configure the popup to be a separate window (and not inline) and the client device does not support popups, ADF Faces automatically shows the page in the current window instead of using a popup window; code changes are not required to facilitate this action.

The page that is displayed in a dialog is an ordinary JSF page, but for purposes of explaining how to implement external dialogs in this chapter, a page that is displayed in a popup dialog is called the dialog page, and a page from which the dialog is opened is called the originating page. A dialog process starts when the originating page opens a dialog (which can contain one dialog page or a series of dialog pages), and ends when the user dismisses the dialog and returns to the originating page.

The tasks for supporting a dialog page flow in an application are:

  1. Define a JSF navigation rule for opening a dialog.

  2. Create the JSF page from which a dialog is opened.

  3. Create the dialog page and return a dialog value.

  4. Optional: Pass a value into a dialog.

  5. Handle the return value.

The tasks can be performed in any order.

19.3.1 How to Define a JSF Navigation Rule for Opening a Dialog

You manage the navigation into a dialog flow by defining a standard JSF navigation rule with a special dialog: outcome.

To define a navigation rule to open a dialog:

  1. In the adfc-config.xml file, create a page flow for your originating page and dialog pages. For detailed procedures, see Section 14.3.3, "How to Add Control Flows".

  2. When creating navigation rules to the dialog pages, the outcome must begin with dialog:. For example, in the login sample application shown in Figure 19-2, the outcome from the Login page to the New Account dialog page is dialog:newAccount.

At runtime, the dialog navigation rules on their own simply show the specified pages in the originating page. But when used with command components with dialog: action outcomes and with useWindow attributes set to true, ADF Faces knows to open the pages in dialogs.

19.3.2 How to Create the JSF Page That Opens a Dialog

In the originating page, you need to use a command component to launch the dialog. The command component's action value needs to be the outcome to the dialog that is to be launched.

To create the JSF Page that opens a dialog

  1. Create a JSF page.

    For more information, see the "Creating a View Page" section in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

  2. Add a command component to the page.

    For more information about adding a command component to a page, see the "Using Buttons and Links for Navigation" section in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

    Note the following when setting the attributes on the command component:

    • action: Set the action attribute to the outcome that navigates to the dialog, as created in Section 19.3.1, "How to Define a JSF Navigation Rule for Opening a Dialog."

      Tip:

      The action value can be either a static string or the return of a method on a managed bean.

      For example, the action attribute on the command component of the Login page is bound to a method that determines whether to navigate to the Orders page or to the Error dialog page, based on the returned outcome. If the method returns dialog:error, the error dialog opens. If the method returns success, the user navigates to the orders page.

    • useWindow: Set to true to have the dialog open.

      Tip:

      When set to false, ADF Faces shows the dialog page in the current window after preserving all of the state of the current page - you do not have to write any code to facilitate this.
    • windowHeight and windowWidth: Set the desired size of the dialog window. These values will set the contentWidth and contentHeight attributes on the popup component for the dialog.

      Tip:

      While the user can change the values of these attributes at runtime, the values will not be retained once the user leaves the page unless you configure your application to use change persistence. For information about enabling and using change persistence, see the "Allowing User Customization on JSF Pages" chapter in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.
    • partialSubmit: Set to true. This prevents the originating page from reloading (and hence being visible only momentarily) when the popup dialog is displayed.

    • windowEmbedStyle: Set to inlineDocument if you want the ensuing dialog to open in a popup that belongs to the originating page. Set to window if you want the ensuing dialog to open in a separate browser.

    • windowModalityType: Set to applicationModal if you want the dialog to be modal. Modal dialogs do not allow the user to return to the originating page until the dialog has been dismissed. Set to modeless if you want the user to be able to go back and forth between the originating page and the dialog.

When a command component is about to open a dialog, it delivers a LaunchEvent event. The LaunchEvent event stores information about the component that is responsible for opening a popup dialog, and the root of the component tree to display when the dialog process starts. A LaunchEvent can also pass a map of parameters into the dialog. For more information, see Section 19.3.5, "How to Pass a Value into a Dialog."

19.3.3 How to Create the Dialog Page and Return a Dialog Value

A dialog page is just like any other JSF page, with one exception. In a dialog page, you must provide a way to tell ADF Faces when the dialog process finishes, that is, when the user dismisses the dialog or series of dialogs.

For example, the New Account page and Account Details page belong in the same dialog process. A dialog process can have as many pages as you desire, you only need to notify the framework that the dialog process has ended once.

You do this declaratively using the returnActionListener tag as a child to the command component used to close the dialog. However, if you need to provide a return value or other action event processing, you can bind the actionListener attribute on the command component to a method that calls the AdfFacesContext.returnFromDialog() method. This method lets you send back a return value in the form of a java.lang.Object or a java.util.Map of parameters. You do not have to know where you are returning the value to - ADF Faces automatically takes care of it.

At runtime, the AdfFacesContext.returnFromDialog() method tells ADF Faces when the user dismisses the dialog. This method can be called whether the dialog page is shown in a popup dialog or in the main window. If a popup dialog is used, ADF Faces automatically closes it.

To close a dialog window an optionally return a value:

  1. To the dialog page, add a command component. If that component will be used to close the window, set the immediate attribute to true.

    If the button will be used to navigate to another page in the dialog process, configure the button as though it were standard navigation, and set the useWindow attribute to false, which will cause the next page to display in the same dialog window, preserving the state of the previous page.

  2. If you need to end the dialog process and close the dialog, but do not need to return a value, in the Component Palette, from the Operations panel, drag a Return Action Listener and drop it as a child to the command component.

    The returnActionListener tag calls the returnFromDialog method on the AdfFacesContext object - no backing bean code is needed.

    No attributes are used with the af:returnActionListener tag. The immediate attribute on the af:commandButton component is set to true: if the user clicks Cancel without entering values in the required Password and Confirm Password fields, the default JSF ActionListener can execute during the Apply Request Values phase instead of the Invoke Application phase, thus bypassing input validation. For more information, see the "Using the JSF Lifecycle with ADF Faces" chapter in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

  3. If you need to end the dialog process and do need to return a value, create a method on a managed bean that handles the action event and returns the needed values using the returnFromDialog method on the current instance of AdfFacesContext.

    Note:

    The AdfFacesContext.returnFromDialog() method returns null. This is all that is needed in the backing bean to handle the Cancel action event.

    For example, when the user clicks Done on the Account Details page, the process ends and returns the user input values. Example 19-2 shows the code for the event handler method to which Done button is bound. The method gets the customer information, then either creates a Faces message for an incorrect password, or sets the values on the new customer object and return that object.

Example 19-2 Action Listener Method for the Done Button in a Managed Bean

public void done(ActionEvent e)
{
  AdfFacesContext afContext = AdfFacesContext.getCurrentInstance();
  String firstname = afContext.getPageFlowScope().get("firstname").toString();
  String lastname = afContext.getPageFlowScope().get("lastname").toString();
  String street = afContext.getPageFlowScope().get("street").toString();
  String zipCode = afContext.getPageFlowScope().get("zipCode").toString();
  String country = afContext.getPageFlowScope().get("country").toString();
  String password = afContext.getPageFlowScope().get("password").toString();
  String confirmPassword =
   afContext.getPageFlowScope().get("confirmPassword").toString();
  if (!password.equals(confirmPassword))
  {
    FacesMessage fm = new FacesMessage();
    fm.setSummary("Confirm Password");
    fm.setDetail("You've entered an incorrect password. Please verify that you've
     entered a correct password!");
    FacesContext.getCurrentInstance().addMessage(null, fm);
  }
  else
  {
    //Get the return value 
    Customer cst = new Customer();
    cst.setFirstName(firstname);
    cst.setLastName(lastname);
    cst.setStreet(street);
    cst.setPostalCode(zipCode);
    cst.setCountry(country);
    cst.setPassword(password);
    // And return it
    afContext.getCurrentInstance().returnFromDialog(cst, null);
    afContext.getPageFlowScope().clear();
  }
}

19.3.4 What Happens at Runtime: Raising the Return Event from the Dialog

When the dialog is dismissed, ADF Faces generates a return event (ReturnEvent). The AdfFacesContext.returnFromDialog() method sends a return value as a property of the return event. The return event is delivered to the return listener (ReturnListener) that is registered on the command component that opened the dialog (for example, the New User commandLink on the Login page). How you would handle the return value is described in Section 19.3.7, "How to Handle the Return Value."

19.3.5 How to Pass a Value into a Dialog

To pass a value into a dialog, you use a LaunchListener listener bound to a handler method for the LaunchEvent. You can use the getDialogParameters() method to add a parameter to a Map using a key-value pair.

To Pass a Value into a Dialog:

  1. Create a handler method for the LaunchEvent that uses the getDialogParameters method to get the parameters from a dialog.

    For example, in the sample application, a new user can enter a name in the Username field on the Login page, and then click the New User? link. When the New Account dialog page displays in a popup dialog, the First Name input field is automatically populated with the name that was entered in the Login page. To accomplish this, you create a handler that uses the getDialogParameters method to put the value of the username field into the dialog, as shown in Example 19-3.

    Example 19-3 LaunchEvent Listener Method for the New User Command Link in a Backing Bean

    public void handleLaunch(LaunchEvent event)
    {
      //Pass the current value of the field into the dialog
      Object usr = username;
      event.getDialogParameters().put("firstname", getUsername());
    }
    // Use by inputText value binding 
    private String username;
    public String getUsername()
    {
      return username;
    }
    public void setUsername(String username)
    {
      this.username = username;
    }
    
  2. Bind the launchListener attribute of the command component used to navigate to the next page, to the handler method created in Step 1.

    Example 19-4 shows the code for the commandLink component, whose launchListener attribute is bound to the handler method.

    Example 19-4 Input Field and New User Command Link on the Login Page

    <af:inputText label="Username" value="#{backing_login.username}"/>
    <af:commandLink id="cmdLink" text="New User?"
                    action="dialog:newAccount"
                    useWindow="true" partialSubmit="true"
                    launchListener="#{backing_login.handleLaunch}"
                    returnListener="#{backing_login.handleReturn}"
                    windowHeight="200" windowWidth="500" />
    
  3. On the resulting page, use the pageFlowScope object to retrieve the key and value via a special EL expression in the format #{pageFlowScope.someKey}, as shown in Example 19-5

    Example 19-5 Input Field on the New Account Page

    <af:inputText label="First name" value="#{pageFlowScope.firstname}"/>
    

19.3.6 What Happens at Runtime: Handling the LaunchEvent

In ADF Faces, a process always gets a copy of all the values that are in the pageFlowScope of the page from which a dialog is launched. When the getDialogParameters() method has added parameters to a Map, those parameters also become available in pageFlowScope, and any page in the dialog process can get the values out of pageFlowScope by referring to the pageFlowScope objects via EL expressions.

Note:

Unlike sessionScope, pageFlowScope values are visible only in the current page flow or process. If the user opens a new window and starts navigating, that series of windows has its own process; values stored in each window remain independent. Clicking on the browser's Back button automatically resets pageFlowScope to its original state. When you return from a process the pageFlowScope is back to the way it was before the process started. To pass values out of a process you would use AdfFacesContext.returnFromDialog(), sessionScope or applicationScope.

19.3.7 How to Handle the Return Value

To handle a return value once the dialog is dismissed, you register a return listener on the command component that launched the dialog. For example, in the sample application, once a new user enters information, that information needs to be handled once the dialog process is complete.

To handle the return value:

  1. Create a handler method for the returnEvent. You use the getReturnValue() method to retrieve the return value, because the return value is automatically added as a property of the ReturnEvent.

    Example 19-6 shows the code for the return listener method that handles the return value.

    Example 19-6 Return Listener Method for the New User Link in a Backing Bean

    public void handleReturn(ReturnEvent event)
    {
      if (event.getReturnValue() != null)
      {
        Customer cst;
        String name;
        String psw;
        cst = (Customer)event.getReturnValue();
        name = cst.getFirstName();
        psw = cst.getPassword();
        CustomerList.getCustomers().add(cst);
        inputText1.setSubmittedValue(null);
        inputText1.setValue(name);
        inputText2.setSubmittedValue(null);
        inputText2.setValue(psw);
      }
    }
    
  2. Bind the returnListener attribute on the command component that launched the dialog to the returnEvent handler method created in Step 1.

19.3.8 What Happens at Runtime: Handling the ReturnEvent on the Launching Component

At runtime in the sample application, when ADF Faces delivers a ReturnEvent to the ReturnListener registered on the commandLink component, the handleReturn() method is called and the return value is processed accordingly. The new user is added to a customer list, and as a convenience to the user any previously submitted values in the Login page are cleared and the input fields are populated with the new information.