Skip Headers
Oracle® Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1)

Part Number B31973-03
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

13 Using Popup Dialogs, Menus, and Windows

This chapter describes how to create and use popup elements in secondary windows using af:popup, af:noteWindow, af:dialog, af:menu, af:panelWindow, and other ADF Faces components to create popup dialogs, menus, and windows on JSF pages. The chapter also describes how to use the ADF Faces dialog framework to create dialogs with a separate page flow in an external browser window.

This chapter includes the following sections:

13.1 Introduction to Using Popup Elements

ADF Faces provides a set of rich client components for hiding and showing information in a secondary window displayed on the page. The af:popup component is an invisible layout control used within a JSF page to display dialogs, windows, and menus. The most commonly used child components of af:popup are af:noteWindow to display read-only information, af:dialog and af:panelWindow to create dialogs and windows, and af:menu to create context menus. The af:popup component can also contain other types of children, in which case its content is displayed as an inline popup selector. To declaratively show a popup element in response to a client-side event, ADF Faces provides the tag af:showPopupBehavior.

ADF Faces also provides a dialog framework to support building pages for a process displayed in an external browser window separate from the parent page. The framework supports multiple dialog pages with a control flow of their own. For example, say a user is checking out of a web site after selecting a purchase and decides to sign up for a new credit card before completing the checkout. The credit card transaction is launched using the dialog framework in an external browser window. The completion of the credit card transaction does not close the checkout transaction on the original page.

The dialog framework is integrated with ADF Faces controller for use with ADF task flows. For more information, see the "Running an ADF Bounded Task Flow as a Modal Dialog" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

The ADF rich client components can be embedded in a dialog with a separate page flow in an external browser window and can also open a dialog in an external browser window.

13.2 Creating Popup Elements

ADF Faces rich client components that support popup elements include the components described Table 13-1.

Table 13-1 Inline Popup Components

Component Description

af:dialog

A layout element that displays its children inside a dialog and delivers DialogEvents when the OK, Yes, No and Cancel actions are activated.

af:noteWindow

A layer that contains read-only information associated with a particular UI component. Note windows are used to display help and messages and are commonly shown on mouse over or on focus gestures.

af:panelWindow

A layout element that displays its children inside a window.

af:popup

A control invisible to the user whose contents will be used in popup windows, such as context menus using af:menu, windows, dialogs and popup selectors.


Both af:dialog and af:panelWindow components support definition help, content displayed when a user moves the cursor over a help icon (a blue circle with a question mark). For more information, see Section 17.5, "Displaying Help for Components".

Figure 13-1 shows a dialog using the af:dialog component for a user to enter search criteria and click OK to submit the entry, or exit the dialog by clicking Cancel or closing the dialog.

Figure 13-1 af:dialog Component

Inline dialog

The af:dialog component is contained in the invisible control, af:popup. The dialog control delivers OK and Cancel actions when intercepted on the client by a dialogListener listener. For information about creating an inline dialog, see Section 13.2.4, "How to Create a Dialog".

Figure 13-2 shows a note window using af:noteWindow component that contains read-only information aligned to the associated word.

Figure 13-2 af:noteWindow Component

Note window component illustrated.

Figure 13-3 shows a panel window that displays a list box in its content.

Figure 13-3 af:panelWindow Component

Panel window component illustrated.

The af:panelWindow component is nested in the invisible control, af:popup. For more information, see Section 13.2.5, "How to Create a Panel Window".

Figure 13-4 shows a context menu where the user can select the display type of a set of files in an application.

Figure 13-4 Context Menu

Popup menu with display type for a set of files.

The af:menu component is contained in a facet. For more information, see Section 13.2.6, "How to Create a Context Menu".

13.2.1 Showing and Hiding Popup Elements

The best way to show a popup element is to add af:showPopupBehavior to a command component anywhere on the page. Activating the command will show the popup element. For detailed information, see Section 13.3, "Using Command Components to Show Popup Elements". The built-in controls for the af:dialog, af:noteWindow, af:panelWindow, and af:menu components will close automatically upon completion, and inline selectors will automatically be dismissed whenever a user clicks outside its content. With ADF Faces rich client components, JavaScript is not needed to show or hide popups.

13.2.2 Delivering Content to the Client

By default, the content of the popup element is not sent from the server until the popup element is displayed. This represents a trade-off between the speed of showing the popup element when it is opened versus the speed of rendering the parent page. Once the popup element is loaded, by default the content will be kept cached on the client for rapid display.

You can modify this content delivery strategy by setting the contentDelivery attribute on the af:popup component to one of the following options:

  • lazy - The default strategy previously described. The content is not loaded until you show the popup element once, after which it is cached.

  • immediate - The content is loaded onto the page immediately, being displayed as rapidly as possible. Use this strategy for popup elements that are consistently used by all users every time they use the page.

  • lazyUncached - The content is not loaded until the popup element is displayed, and then the content is reloaded every time you show the popup element. Use this strategy if the popup element shows data that can become stale or outdated.

13.2.3 Using Dialog Buttons

The ADF Faces af:dialog component provides built-in partial-submit command buttons. These components simulate a browser window using HTML layers and JavaScript. The button configurations use the type property of the af:dialog to define different button combinations including:

  • okCancel

  • yesNoCancel

  • ok

  • yesNo

  • cancel

  • none

The labels on the buttons can be changed using the following dialog properties:

  • affirmativeTextAndAccessKey for the Yes or OK buttons

  • cancelTextAndAccessKey for the Cancel button

  • noTextAndAccessKey for the No button

The af:dialog component provides a dialogListener property that expects a method expression to be used in place of an actionListener action. The DialogEvent event passed to the listener has an outcome property along with its associated constants that can be used to determine what button was pressed.

The dialog cancel button and close icon in the upper right-hand corner of the dialog generates client-only events not propagated to the server. The cancel button will close the dialog without validation.

The other buttons (Yes, OK, and No), specified using the dialog type property, will also automatically hide the dialog when selected if no messages are returned from the partial page update that are of an error or fatal severity level. Warning and informational messages are not considered in this case.

Additional buttons can be added to the dialog footer by placing these commands in an af:buttonBar facet within the content of the dialog. These buttons will not invoke the DialogEvent event and must also be partial-submit buttons. Commands are supported in the content of the dialog, outside of the button bar, but these must also be partial-submit commands.

13.2.4 How to Create a Dialog

The af:popup component must be contained within an af:form component on the page.

To create an inline dialog:

  1. Insert the af:popup component in the JSF page.

  2. Nest the af:dialog component inside the af:popup component.

  3. For the af:dialog component, set the following attributes:

    • title: The text displayed as the title on the dialog window.

    • dialogListener: The EL expression method reference to a dialog listener method.

  4. Insert a browser input component such as af:inputText and set the required attribute to true and the label attribute to Required. Use a layout component like af:panelGroupLayout to contain the input component.

Example 13-1 shows an example of code generated by JDeveloper when you create a dialog and Figure 13-1 shows the resulting dialog.

Example 13-1 Dialog Component

<af:popup id="searchDialog">
  <af:dialog title="Search"
    dialogListener type="#{myBean.buttonClicked}">
      <af:panelGroupLayout>
        <af:inputText required="true" label="Required:"/>
    </af:panelGroupLayout>
  </af:dialog>
<af:popup>
  
public class MyBean
{
  public void dialogButtonClicked(oracle.adf.view.rich.event.DialogEvent dialogEvent)
  {
    System.out.println("The dialog outcome is:"+ dialogEvent.getOutcome());
  }
}

13.2.5 How to Create a Panel Window

The af:popup component must be contained within an af:form component.

To create an inline window:

  1. Insert the af:popup component in the JSF page.

  2. Insert the af:panelWindow component inside the af:popup component.

  3. For the af:panelWindow component, set the following attributes:

    • title: The text displayed as the title on the window.

    • modal: Whether or not the window must be dismissed before returning to the parent application. By default set to false.

  4. Insert the browser input component such as af:selectManyListbox inside the af:panelWindow component. Use a layout component like af:panelGroupLayout to contain the parent input component.

  5. Insert the children of af:selectManyListbox such as af:selectItem, af:selectItems, or f:selectItem components to complete the input component.

Example 13-2 shows the code generated by JDeveloper when you create a panel window and Figure 13-3 shows the resulting window.

Example 13-2 Popup, panelWindow, and selectMany Listbox Components

<af:popup id="popupWindow">
  <af:panelWindow modal="true" title="Test Window">
    <af:panelGroupLayout>
      <af:selectManyListbox value="#{demoInput.manyListValue1}">
        <af:selectItem label="coffee" value="bean" shortDesc="Coffee from Kona"/>
        <f:selectItem itemLabel="tea" itemValue="leaf" itemDescription="Tea from China"/>
        <af:selectItem disabled="true" label="orange juice" value="orange"/>
        <f:selectItem itemDisabled="true" itemLabel="wine" itemValue="grape"/>
        <af:selectItem label="milk" value="moo"/>
        <f:selectItems value="#{demoInput.selectItems}"/>
      </af:selectManyListbox>
    </af:panelGroupLayout>
  </af:panelWindow>
</af:popup>

13.2.6 How to Create a Context Menu

The af:popup component must be contained within an af:form component.

To create an inline context menu:

  1. Insert the af:commandToolbarButton component in the JSF page and set the text attribute to display the name of the button. Use the icon attribute to set the image to use on the button.

  2. Insert the f:facet component inside the af:commandToolbarButton component and set the name attribute to popup.

  3. Insert the af:menu tag inside the f:facet component.

  4. Inside the f:facet component insert a series of af:commandMenuItem components to define the items in the menu. For more information about creating menus, see Chapter 14, "Using Menus, Toolbars, and Toolboxes".

Example 13-3 shows an example of code generated by JDeveloper when you create a menu contained in a popup facet and Figure 13-4 shows the resulting popup menu.

Example 13-3 Popup Facet and Menu Components

<af:commandToolbarButton text="Arrange" icon="/images/arrange.gif">
  <f:facet name="popup">
    <af:menu>
      <af:commandMenuItem partialSubmit="true" text="Thumbnails"/>
      <af:commandMenuItem partialSubmit="true" text="Tiles"/>
      <af:commandMenuItem partialSubmit="true" text="Icons"/>
      <af:commandMenuItem partialSubmit="true" text="List"/>
      <af:commandMenuItem partialSubmit="true" text="Details"
         icon="/images/status_bullet.png"/>
    </af:menu>
  </f:facet>
</af:commandToolbarButton>

13.3 Using Command Components to Show Popup Elements

ADF Faces client behavior tags provide declarative solutions to common client operations that you would otherwise have to write yourself using JavaScript, and register on components as client listeners. In this release, ADF Faces supports the client behavior af:showPopupBehavior to use in place of a client listener.

13.3.1 How to Use the af:showPopupBehavior Tag

Typically, you would associate an af:showPopupBehavior tag with a command component, such as af:commandButton, to provide a button for users to activate and then display the contents in an inline popup element.

To use an af:showPopupBehavior tag:

  • Nest the af:showPopupBehavior tag inside the component that would trigger the popup element (for example, a command button component).

    Example 13-4 shows sample code that displays some text in the af:popup component with the id “popup1" when the button "Click Me" is clicked.

Example 13-4 showPopupBehavior Associated with af:commandButton component

<af:commandButton text="Click me" id="button">
  <af:showPopupBehavior popupId="popup1" alignId="button" align="afterEnd"/>
</af:commandButton>

<af:popup id="popup1">
  <af:panelGroupLayout layout="vertical">
    <af:outputText value="Some"/>
    <af:outputText value="popup"/>
    <af:outputText value="content"/>
  </af:panelGroupLayout>
</af:popup>

When you use an af:showPopupBehavior tag, the attributes you would set on af:showPopupBehavior are:

  • popupId: Specify the id of the af:popup component whose contents you want to display in a popup element.

  • alignId and align: Use alignId to specify the id of the component with which to align the popup element contents. Then use align to specify an alignment position that is relative to the component identified by alignId.

    For example, the code in Example 13-4 tells ADF Faces to align the popup contents with the af:commandButton that is identified by the id button, and to use the alignment position of afterEnd, which aligns the popup element underneath the button with the popup's upper right-hand corner aligned with the lower right-hand corner of the button. The right edges of the button and the popup are aligned, as shown in Figure 13-5.

    Figure 13-5 Button and Popup Contents

    button and popup contents
  • triggerType: Specify the event type to use to trigger the popup element. The default is action, because typically, you would associate af:showPopupBehavior with a command component. When the command component is clicked, an action event is fired, which triggers the display of the popup element.

    If you associate the af:showPopupBehavior tag with some other non command component, such as af:outputText, set the triggerType attribute on the af:showPopupBehavior tag to contextMenu, which will display a popup context menu. Example 13-5 shows sample code that displays a context menu when users right-click on the text rendered by af:outputText and Figure 13-6 shows the sample context menu generated.

    Example 13-5 showPopupBehavior Associated with af:outputText component

    <af:popup id="popupMenu">
      <af:menu>
        <af:commandMenuItem text="Cut"/>
        <af:commandMenuItem text="Copy"/>
        <af:commandMenuItem text="Paste"/>
      </af:menu>
    </af:popup>
    
    <af:outputText value="Right-click For A Popup Menu">
      <af:showPopupBehavior popupId="popupMenu"
                            triggerType="contextMenu"/>
    </af:outputText>
    

    Figure 13-6 af:outputText and Popup Menu

    output text and popup

    To show a non modal popup element when the mouse appears over the trigger component and also to hide it when the mouse leaves the trigger component, use mouseHover attribute. Example 13-6 shows sample code that displays a popup element when users place focus on the text rendered by the af:outputText component and Figure 13-7 shows the sample popup generated.

    Example 13-6 af:outputText and mouseHover Popup Trigger

    <af:popup id="popup4">
        <af:outputText value="Your mouse is hovering over this trigger button right now."/>
    </af:popup>
        <af:outputText value="This demo shows a popup from a mouseHover trigger type."/>
         <af:spacer width="5"/>
         <af:commandButton
           immediate="true"
           text="Show Popup"
           clientComponent="true"
           id="popupButton4">
             <af:showPopupBehavior
               popupId="popup4"
               alignId="popupButton4"
               align="afterStart"
               triggerType="mouseHover"/>
            </af:commandButton>
    

    Figure 13-7 mouseHover Trigger on Popup

    Mouse hover target on popup

13.4 External Browser Window

While it takes longer for a web browser to create, sometimes you might want to display a page in a new browser window instead of displaying it in the same window containing the current page. In the external dialog, you might let the user enter or select information, and then return to the original page to use that information. Ordinarily, you would need to use JavaScript to open the dialog, manage the process, and create code for managing cases where popups are not supported on certain client devices such as a PDA. With the dialog framework, ADF Faces has made it easy to open a new browser window and manage dialogs and processes without using JavaScript.

Consider a simple application that requires users to log in to see their orders. Figure 13-8 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 13-8 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 to display in a popup dialog, as shown in Figure 13-9.

Figure 13-9 Error Page in a Popup

Error message displayed in a popup dialog

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, as shown in Figure 13-10.

Figure 13-10 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, as shown in Figure 13-11.

Figure 13-11 New Account Page in a Popup Dialog

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 13-12. 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 13-12 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 13-13. The new user can then proceed to enter the new password and log in successfully.

Figure 13-13 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.

13.4.1 How to Create External Dialogs and Page Flows

To make it easy to support dialogs in your applications, ADF Faces has built in the dialog functionality to components that implement ActionSource action (such as af:commandMenuItem and af:commandButton). For ADF Faces to know whether or not to open a page in a new browser window dialog from an ActionSource component, four 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.

  • The client device must support popup elements.

Note:

If the useWindow attribute is false or if the client device does not support popup elements, 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 new browser window dialogs 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.

13.4.1.1 Defining a JSF Navigation Rule for Opening a Dialog

You manage the navigation into a dialog by defining a standard JSF navigation rule with a special dialog: outcome. Using the dialog sample application shown in Figure 13-8, three navigation outcomes are possible from the Login page:

  • Show the Orders page in the same window (successful login).

  • Show the Error dialog page in a dialog (login failure).

  • Show the New Account dialog page in a dialog (new user).

Example 13-7 shows the navigation rule for the three navigation cases from the Login page (login.jspx).

Example 13-7 Dialog Navigation Rules in the faces-config.xml File

<navigation-rule>

  <!-- Originating JSF page -->
  <from-view-id>/login.jspx</from-view-id>

  <!-- Navigation case for the New Account dialog page (new user)-->
  <navigation-case>
    <from-outcome>dialog:newAccount</from-outcome>
    <to-view-id>/new_account.jspx</to-view-id>
  </navigation-case>

  <!-- Navigation case for the Error dialog page (upon login failure) -->
  </navigation-case>
    <from-outcome>dialog:error</from-outcome>
    <to-view-id>/error.jspx</to-view-id>
  </navigation-case>

  <!-- Navigation case for the Orders page (upon login success) -->
  </navigation-case>
    <from-outcome>orders</from-outcome>
    <to-view-id>/orders.jspx</to-view-id>
  </navigation-case>

</navigation-rule>

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. This is described in the next step.

13.4.1.2 Creating the JSF Page That Opens a Dialog

In the originating page from which a popup dialog is launched, you can use either an action method or a static action outcome on the ActionSource component. Whether you specify a static action outcome or use an action method that returns an action outcome, this action outcome must begin with dialog:.

The page flow we are describing uses an action method binding on the commandButton component to determine programmatically whether to navigate to the Orders page or to the Error dialog page, and the page flow also uses a static action outcome on the commandLink component to navigate directly to the New Account dialog page. Both command components are on the Login page. Example 13-8 shows the code for the Login commandButton component.

Example 13-8 Login Button on the Login Page

af:commandButton id="cmdBtn"
                 text="Login"
                 action="#{backing_login.commandButton_action}"
                 useWindow="true"
                 windowHeight="200"
                 windowWidth="500"
                 partialSubmit="true"/>

The attributes useWindow, windowHeight, and windowWidth are used in opening pages in popup dialogs. These attributes are ignored if the client device does not support popup dialogs.

When useWindow="true" ADF Faces knows to open the dialog page in a new popup dialog. The windowHeight and windowWidth attributes specify the size of the popup dialog.

Tip:

Set the partialSubmit attribute on the commandButton component to true. This prevents the originating page from reloading (and hence being visible only momentarily) when the popup dialog is displayed.

The action attribute on the af:commandButton component specifies a reference to an action method in the page's backing bean, Login.java. The action method must return an outcome string, which JSF uses to determine the next page to display by comparing the outcome string to the outcomes in the navigation cases defined in the faces-config.xml file. The code for this action method is shown in Example 13-9.

Example 13-9 Action Method Code for the Login Button

public String commandButton_action()
{
  String retValue;
  retValue = "orders";
  _cust = getListCustomer();
  if (_cust == null || !password.equals(_cust.getPassword()))
  {
    retValue = "dialog:error";
  }
  
  return retValue;
}

Example 13-10 shows the code for the New User commandLink component that uses a static action outcome.

Example 13-10 New User Command Link on the Login Page

<af:commandLink id="cmdLink" 
                text="New User?"
                action="dialog:newAccount"
                useWindow="true"
                partialSubmit="true"
                windowHeight="200"
                windowWidth="500" />

Instead of referencing an action method, the action attribute value is simply a static outcome string that begins with dialog:.

At runtime, ADF Faces uses the attribute useWindow="true" in conjunction with an action outcome that begins with dialog: to determine whether to start a dialog process and open a page in a popup dialog (assuming dialog: navigation rules have been defined in the faces-config.xml file).

If the action outcome does not begin with dialog:, ADF Faces does not start a process or open a popup dialog even when useWindow="true". Conversely, if the action outcome begins with dialog:, ADF Faces does not open a popup dialog if useWindow="false" or if useWindow is not set, but ADF Faces does start a new process.

If the client device does not support popup dialogs, 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.

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 13.4.1.4, "Passing a Value into a Dialog".

13.4.1.3 Creating the Dialog Page and Returning a Dialog Value

The dialog pages in our sample page flow are the Error page, the New Account page, and the Account Details page. The dialog process for a new user actually contains two pages: the New Account page and the Account Details page. The dialog process for a user login failure contains just the Error page.

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. Generally, you do this programmatically or declaratively name a command component. Example 13-11 shows how to accomplish this programmatically using a Cancel button on the Error page.

Example 13-11 Cancel Button on the Error Page

<af:commandButton text="Cancel"
                  actionListener="#{backing_error.cancel}" />

The actionListener attribute on the af:commandButton component specifies a reference to an action listener method in the page's backing bean, Error.java. The action listener method processes the action event that is generated when the Cancel button is clicked. You call the AdfFacesContext.getCurrentInstance()returnFromDialog() method in this action listener method, as shown in Example 13-12.

Example 13-12 Action Listener Method for the Cancel Button in a Backing Bean

public void cancel(ActionEvent actionEvent)
{
  AdfFacesContext.getCurrentInstance().returnFromDialog(null, null);
}

Note:

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

To accomplish telling ADF Faces that the dialog process is finished declaratively on the Account Details dialog page, attach a af:returnActionListener tag to the Cancel button component, as shown in Example 13-13. The af:returnActionListener tag calls the returnFromDialog method on the AdfFacesContext - no backing bean code is needed.

Example 13-13 Cancel Button on the Account Details Page

<af_commandButton text="Cancel" immediate="true">
  <af:returnActionListener/>
</af:commandButton>

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 Chapter 4, "The JSF Lifecycle".

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, but you only need to call AdfFacesContext.getCurrentInstance().returnFromDialog() once.

The same af:returnActionListener tag or AdfFacesContext.getCurrentInstance().returnFromDialog() method can also be used to end a process and return a value from the dialog. For example, when the user clicks Done on the Account Details page, the process ends and returns the user input values. Example 13-14 shows the code for the Done button.

Example 13-14 Done Button on the Account Details Page

<af:commandButton text="Done"
                  actionListener="#{backing_new_account.done}" />

The actionListener attribute on the af:commandButton component specifies a reference to an action listener method in the page's backing bean, New_account.java. The action listener method processes the action event that is generated when the Done button is clicked. Example 13-15 shows the code for the action listener method, where the return value is retrieved, and then returned using the AdfFacesContext.returnFromDialog() method.

Example 13-15 Action Listener Method for the Done Button in a Backing 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();
  }
}

The AdfFacesContext.returnFromDialog() 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.

In the sample application, when the user clicks the Cancel button on the Error page or Account Details page, ADF Faces calls AdfFacesContext.returnFromDialog(), (which returns null), closes the popup dialog, and returns to the originating page.

The first page in the new user dialog process is the New Account page. When the Details button on the New Account page is clicked, the application shows the Account Details dialog page in the same popup dialog (because useWindow="false"), after preserving the state of the New Account page.

When the Done button on the Account Details page is clicked, ADF Faces closes the popup dialog and the AdfFacesContext.returnFromDialog() method returns cst to the originating page.

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 (which would be the New User commandLink on the Login page). How you would handle the return value is described in Section 13.4.1.5, "Handling the Return Value".

13.4.1.4 Passing a Value into a Dialog

The AdfFacesContext.returnFromDialog() method lets you send a return value back from a dialog. Sometimes you might want to pass a value into a dialog. To pass a value into a dialog, you use a LaunchListener listener.

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 register a LaunchListener listener on the command component that opened the dialog (which would be commandLink). Example 13-16 shows the code for the commandLink component.

Example 13-16 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" />

The launchListener attribute on af:commandLink specifies a reference to a listener method for the LaunchEvent in the page's backing bean, Login.java. In the launchListener method you use the getDialogParameters() method to add a parameter to a Map using a key-value pair. Example 13-17 shows the code for the launchListener method.

Example 13-17 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;
}

To show the parameter value in the New Account dialog page, use the ADF Faces pageFlowScope to retrieve the key and value via a special EL expression in the format #{pageFlowScope.someKey}, as shown in Example 13-18.

Example 13-18 Input Field on the New Account Page

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

Note:

You can use pageFlowScope with all JSF components, not only with ADF Faces components.

At runtime when a command component is about to launch a dialog (assuming all conditions have been met), ADF Faces queues a LaunchEvent. This event stores information about the component that is responsible for launching a dialog, and the root of the component tree to display when the dialog process starts. Associated with a LaunchEvent is a launchListener, which takes the LaunchEvent as a single argument and processes the event as needed.

In the sample application, when ADF Faces delivers the LaunchEvent to the launchListener registered on the commandLink component, the handleLaunch() method is called and the event processed accordingly.

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.

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.

13.4.1.5 Handling the Return Value

To handle a return value, you register a return listener on the command component that launched the dialog, which would be the New User link component on the Login page in the sample application. Example 13-19 shows the code for the New User link component.

Example 13-19 New User Command Link on the Login Page

<af:commandLink id="cmdLink" text="New User?"
                action="dialog:newAccount"
                useWindow="true" partialSubmit="true"
                returnListener="#{backing_login.handleReturn}"
                windowHeight="200" windowWidth="500" />

The returnListener attribute on commandLink specifies a reference to a return listener method in the page's backing bean, Login.java. The return listener method processes the return event that is generated when the dialog is dismissed. Example 13-20 shows the code for the return listener method that handles the return value.

Example 13-20 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);
  }
}

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

At runtime in the sample application, when ADF Faces delivers a ReturnEvent to the ReturnListener registered on the af: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.