How to use JavaServer Faces components with Ajax in IBM Rational Application Developer

Illustrated by a step-by-step example of building a weather forecast application in IBM Rational Application Developer by using Ajax, JSF, and SDO

This article walks you through the steps and code work needed to design and implement a weather forecast application by using Ajax with a Relational Record List, Combo Box, Panels-Tabbed, and Data Tree components in IBM® Rational® Application Developer. It also explains a technique for accessing data elements from a Relational Record List that has two related tables.

Sami Joueidi (samijou@us.ibm.com), Senior Rational Engineer, IBM Japan

Sami Joueidi holds a master's degree in electrical engineering. He is an IBM Certified Architect and serves on the IBM Architecture Board. As part of the IBM Rational team, he focuses on software architecture management.



25 March 2008

Also available in Chinese

About this article

The article guides you, step-by-step, through the process of designing and developing an application by using Asynchronous JavaScript and XML (AJAX, hereafter Ajax) with IBM® Rational® Application Developer Version 7.0. It includes practical techniques for how to use various Java™Server Faces (JSF) components in conjunction with Ajax and shows you how to overcome the built-in caching in a Relational Record List. It explains how to initialize the session scope variable to display the data corresponding to the initial value of the Combo Box control at application startup.

You will also learn the steps to add a Tabbed Panel control to a Web page and to configure a Data Tree to work with a Relational Record List. It concludes by showing you a technique for accessing data elements from a Relational Record List that consists of two related tables.

This article does not cover the details of each of the technologies used in the examples, but there are several articles cited in Resources that describe each of them if you want to learn more. The main technologies used are Ajax, JSF using IBM Enhanced Faces components, and service data objects (SDOs).

Knowledge and system requirements

The instructions assume a basic knowledge of the Java™ language, but you do not need extensive experience in Java. However, this article assumes that you have a basic knowledge of using the Rational Application Developer development environment. It also assumes you have basic knowledge of Ajax and SDOs. See Resources for more information on these technologies.

To run the examples in this article, you must have either IBM® Rational® Software Architect or Rational Application Developer installed on your workstation. The version of Rational Application Developer used in this article is 7.0.


Create the WeatherForecastDB database

To create the application database, you will complete these three tasks:

  1. Download and import the CreateWeatherForecastDatabase.zip into your workspace.
  2. Create the supporting Derby database named WeatherForecastDB by using the supplied Java application.
  3. Create a connection to the WeatherForecastDB database.

Download and import the Java project

The weather forecast application uses a Derby database for its information. For this example, you will use a Java application to create the database. If you want to learn more about how to manually create a database by using the Data perspective in Rational Application Developer, read the IBM® developerWorks® article titled "Hello World (Updated): Rational Application Developer V7, Create Java, Web Service, and database applications" (see Resources for a link).

To begin, follow these steps:

  1. Download and save the CreateWeatherForecastDatabase.zip file to your computer (see Downloads).
  2. Start Rational Application Developer on your desktop. If a window appears asking for the workspace directory, enterc:\temp\weatherforecast, and then click OK.
  3. Close the Welcome screen if it appears.
  4. Import the CreateWeatherForecastDatabase.zip file:
    1. From the workbench, select Window > Open Perspective > Java to switch to the Java perspective.
    2. Select File > Import > Other > Project Interchange to import the project into your workspace.
    3. Click Next.
    4. Next to From zip file, click Browse to navigate to where you saved the CreateWeatherForecastDatabase.zip file.
    5. Click Select All.
    6. Click Finish.

Next, set up the Java build path for the Java project.

  1. Right-click CreateWeatherForecastDatabase in the Package Explorer view (Figure 1) to set the Java build path, in case it did not carry over when you imported the project.
Figure 1. Set the Java build path
Setting the Java build path
  1. Select Properties (see Figure 2).
  2. Click Java Build Path.
  3. Click the Libraries tab. Ensure that the path for the derby.jar file has been added. If you can't find it, you will need to add it manually by following these steps:
    1. Click Add External JARs.
    2. Enter this path:
      C:\Program Files\IBM\SDP70Shared\plugins\com.ibm.datatools.db2.cloudscape.driver_1.0.0.v200610121320\driver\derby.jar
    3. Click Open.
    4. Click OK.
Figure 2. Path for the derby.jar file
Selecting the path

Important note:
These instructions assume that you have selected the default installation for Rational Application Developer Version 7.0, and that you are using Embedded Derby file, which is included with Rational Application Developer, with no database security.

If not, please modify the path for derby.jar file accordingly in the Java build path and class location for the connection. Also, you might need to edit the entries for the driver, protocol, user ID, and password in the CreateWeatherForecastTablesDB.java file.

Create the WeatherForecastDB database

Now you're ready to create the WeatherForecastDB database:

  1. Under the Package Explorer, expand CreateWeatherForecastDatabase > default package.
  2. Right-click CreateWeatherForecastTablesDB.java, and then select Run As > Java Application.
  3. Watch for the last message, "Committed transactions," in the Console view. This message indicates that the Java application has completed these tasks successfully:
    • Created the WeatherForecastDB database in the c:\temp directory
    • Created the tables, primary keys, foreign keys, and indexes
    • Loaded the test data to be used by the examples

Create the database connection

Now that you have created the WeatherForecastDB database, you need to create the database connection. You will create the connection to the WeatherForecastDB database in the Database Explorer view.

Alternative:
The steps that follow show how to manually create a database connection. If you prefer, you can create a connection by using the SDO Creation wizard.

  1. Select Window > Open Perspective > Other to switch to the Data perspective.
  2. Select the Show all check box, and then select Data.
  3. Click OK.
  4. If you are asked to enable the Core Database Development capability, click OK.
  5. In the Database Explorer view, right-click Connections (in the bottom-left corner), and click New Connection.
  6. Under Connection identification (Figure 3), leave Use default naming convention checked.
  7. Select Derby 10.1.
  8. For Database location, enter C:\temp\WeatherForecastDB.
  9. Uncheck Create the database if required, because you already created the database.
  10. For Class location, enter this path:
    /C:/Program Files/IBM/SDP70Shared/plugins/com.ibm.datatools.db2.cloudscape.driver_ 1.0.0.v200610121320/driver/derby.jar
  11. Under User Information, enter Weather for the User ID. Leave the Password blank.
  12. Click Test Connection to see if a connection can be established. If it can be, you should see a window stating "Connection to Derby is successful."
  13. Click OK to close the window.
  14. Click Next.
  15. Click Finish to create the connection.
Figure 3. Connection parameters
Screen capture of the connection parameters
  1. Under the Database Explorer view, expand WeatherForecastDB connection to see the database tables that Figure 4 shows (LARGESTCITIES, STATES, STATESANDCITIES and TENDAYFORECAST).
Figure 4. Database tables
Screen capture of the database tables

The diagram in Figure 5 shows the tables that were created and their relationships.

Figure 5. Tables and their relationships
Screen capture of tables and relationships

Create the weather forecast application

Now that you have the groundwork laid out, the following are the next steps:

  1. Create the weather forecast dynamic Web project.
  2. Create a JSP page using JavaServer™ Faces technology.
  3. Create session scope variables.
  4. Create Relational Record Lists.
  5. Add these components and Ajax support to the JSP page:
    • Table
    • Combo Box
    • Panel Group-Box
  6. Deploy and test the weather forecast application.
  7. Turn off caching for the largestCityPopulationSB Relational Record List.
  8. Deploy and test the application again.
  9. Initialize the session scope variable.
  10. Deploy and test the application again.

Create the WeatherForecastProject project

The first part of the weather forecast application displays the population for a given city.

In this section, you will create the dynamic Web project and your first JavaServer Page (JSP) that uses JavaServer™ Faces (JSF) technology. The basic weather forecast application will use a Combo Box to display the various United States cities. Based on the selection, the city population and ranking are fetched from the database and displayed in a Relational Record List. JSF technology is used for building this dynamic Web application.

  1. From the menu bar, click File > New > Project.
  2. From Select a wizard, check Show All Wizards.
  3. Scroll down and select Web > Dynamic Web Project.
  4. Click Next.
  5. If prompted, click OK to confirm that you want to enable Web Development.
  6. In the Name field, enter WeatherForecastProject.
  7. Important: For Configurations, select Faces Project.
  8. Make sure that the Add project to an EAR check box is checked.
  9. Click Finish.
  10. Click Yes to switch to the Web perspective.
Figure 6. Create the Web project
Creating the Web project

Create the comboBoxExample.jsp JSP page

You now have a new Web project. Your next step is to build the comboBoxExample.jsp page:

  1. Close WebDiagram.gph if it was open.
  2. Right-click WeatherforecastProject, and then select New > Web Page to launch the New Page wizard.
  3. For File Name, type comboBoxExample.jsp.
  4. Under Basic Templates, select JSP.
  5. Click Options, select JavaServer Faces.
  6. Click Close.
  7. Click Finish.
  8. Click Finish.
Figure 7. Create the comboBoxExample.jsp page
Creating the jsp page

The comboBoxExample.jsp file is created under WeatherForecastProject/WebContent. When Rational Application Developer opens that page, you are ready to design the page.

Create a sessionScope variable called largestCityVar

  1. From the Page Data view, which is the lower-left pane in the Web perspective, expand Scripting Variables.
  2. Right-click sessionScope, and then select New > Session Scope Variable.
  3. For the Variable name, enter largestCityVar.
  4. For Type, enter java.lang.String.
  5. Click OK.

Create a Relational Record List called largestCitiesSB

  1. In the Web perspective, go to the Page Data view, which is the lower-left pane.
  2. Right-click Relational Records and select New > Relational Record List.
  3. For Name, enter largestCitiesSB.
  4. Click Next.
  5. Click New.
  6. Select Use an existing connection.

Tip:
You are using the database connection that you previously created manually. If you have not yet created that connection, you can use the SDO Creation wizard here to create the connection to the database.

  1. Select WeatherForecastDB, and click Next.
  2. For User ID, leave it as Weather.
  3. Leave the Password field blank.
  4. Click Next.
  5. Click Finish.
  6. Under Table, scroll down, expand WEATHER, and select LARGESTCITIES.
  7. Click Next.
  8. Click None. You will notice that only LARGEST_CITY is still selected, because it is the primary key.
  9. Click Finish.
Figure 8. Create Relational Record List largestCitiesSB
Creating the connection to the database

Create a Relational Record List called largestCityPopulationSB

Note:
This time, you will apply a filter to the Relational Record List to select only the records that correspond to the city, as specified by the largestCityVar sessionScope variable.

  1. From the Page Data tab, which is in the lower-left pane in the Web perspective, right-click Relational Records and select New > Relational Record List.
  2. For the name, enter largestCityPopulationSB.
  3. Click Next.
  4. Under Table, scroll down, expand WEATHER, and select LARGESTCITIES.
  5. Click Next.
  6. Under Tasks, click Filter results.
  7. Click the plus sign (+).
  8. Select LARGEST_CITY, and then, from the drop-down menu for Column, select LIKE.
  9. Select Variable, and then click the button with the ellipses (three dots: ...).
  10. Expand sessionScope, and select largestCityVar.
Figure 9. Filter settings
Filtering settings for results
  1. Click OK.
  2. Click OK again.
  3. Click Close.
  4. Under Tasks, click Order Results.
  5. Move Ranking and LARGEST_CITY under Order by.
  6. Click Close.
Figure 10. Order results
Setting the rank order
  1. Click Finish.

Add the components and Ajax support to the JSP page

Add a table to the JSP page

  1. Under HTML Tags, drag a table onto the page by using the palette, and specify these dimensions:
    • Rows: 1
    • Columns: 2
    • Table width: 100%
    • Border width: 0 pixels
Figure 11. Specify table dimensions
Using the palette and specifying table dimensons
  1. Click OK.
  2. 5. In the Properties view for the table, make sure the Table is selected, click the table leaf, and specify these preferences:
    • Align: Left
    • Width: 100%
    • Height: 100%
Figure 12. Table leaf alignment
Screen capture of the table leaf alignment
  1. In the Properties view for the cell, with the cursor in the first cell, specify this layout:
    • Horizontal: Left
    • Vertical: Top
    • Width: 20%
    • Wrap lines automatically: Not checked
  2. Put your cursor in the second cell, and specify this layout:
    • Horizontal: Left
    • Vertical: Top
    • Width: 80%
    • Wrap lines automatically: Not checked
  3. Click File > Save All to save your work.

Add a Combo Box

  1. In the first cell, type Select a City: .
  2. From under Enhanced Faces Components drawer, next to the text that you just typed, drag a Combo Box into the first cell.

Add a Panel-Group Box

  1. Drag a Panel-Group Box into the second cell. This is the area of the page that will be updated by the Ajax request.
  2. For Select Type, select Box and click OK.
Figure 13. Add a Panel-Group Box
Adding a group box

Adjust the Panel properties

  1. Select the panel and switch to the Properties view.
  2. Make sure that hx:panelBox is selected.
  3. Enter these values:
    • Width: 100%
    • Height: 100%
    • Vertical: Top
    • Horizontal: Left

Add Ajax support to the panel

  1. Select the Panel Box and switch to the Properties view.
  2. Make sure that hx:panelBox is selected.
  3. Select the Ajax leaf for the hx:panelBox.
  4. Check the Allow Ajax updates check box.
  5. Click Submit as the Ajax request type.
Figure 14. Select Ajax request type
Adding support to the panel
  1. Click File > Save All to save your changes.

Initiate the Ajax request by using the Combo Box onchange event

  1. Select the Combo Box component.
  2. Switch to the Quick Edit view (next to the Properties view).
  3. In the Quick Edit view:
    • Select the onchange event from the list of events on the left side.
    • Click the Use predefined behavior check box.
    • Select the Invoke Ajax behavior action on the specific tag.
    • Select box1 as the target, and then press the Tab key.
  4. Click File > Save All to save your work.
Figure 15. Use the onchange event to initiate the Ajax request
Using events to initiate the request

Bind the largestCitiesSB Relational Record List to the Combo Box

  1. From the Page Data tab, expand Relational Records > largestCitiesSB (Service Data Object) > largestCitiesSB(LARGESTCITIES).
  2. Drag LARGEST_CITY(String) onto the Combo Box. The Combo Box gets populated with the largest cities at run time.

Add All Cities to the Combo Box as an additional choice

  1. Switch to the Combo Box Properties view.
  2. Click Add Choice, and enter these values:
    • Label:All Cities (All Cities shows the information for all of the cities in the database.)
    • Value:% (The % is a SQL wild card.)
  3. Switch to the Combo Box Properties view.
  4. Select the choice All Cities and click Move Up.

Bind the largestCityVar variable to the Combo Box

  1. From the Page Data tab, expand Scripting Variables > sessionScope.
  2. Drag largestCityVar onto the Combo Box. The variable will get updated with the Combo Box value (either with the largest city name when a specific city is selected or with the % wild card when All Cities is selected).

The Combo Box Properties should now look like Figure 16.

Figure 16. Updated Combo Box properties
Combo box properties screen capture

Add the largestCityPopulationSB Relational Record List to the Panel-Box

  1. From the Page Data tab, expand Relational Records > largestCityPopulationSB (Service Data Object).
  2. Drag largestCityPopulationSB (LARGESTCITIES) onto the Panel-Box so that you can display the information about the selected city.
  3. Edit the Labels (by clicking inside each label) as Table 1 shows (also see Figure 17):
Table 1. Edit labels in this order
Column NameLabelControl Type
RANKINGRankingOutput Field
LARGEST_CITYLargest CityOutput Field
STATEStateOutput Field
POPULATIONPopulationOutput Field

Figure 17. Edited labels
Modifying labels
  1. Click Finish to close the Configure Data Controls window.

Alternate the background color for each row in the table

  1. Click the Display options leaf.
  2. Make sure that Row classes shows rowClass1, rowClass2 (see Figure 18). These are two CSS classes, separated by a comma, with different background colors. These values are usually defined in theme file stylesheet.css file inside of the project.
Figure 18. CSS classes for alternating row colors
Setting different values
  1. Remove the columnClass1 entry from the Classes column, because the columnClass overrides the rowClasses when the CSS is applied to the table.
Figure 19. Remove the columnClass1 entry
Removing the entry
  1. Select File > Save All to save your changes. Your page should now look like Figure 20.
Figure 20. Modified page
Modifying the page

That's it. You are ready to test the page and observe its behaviors.

Test the page

  1. Under WeatherForecastProject/WebContent, right-click the comboBoxExample.jsp file, and select Run As > Run on Server.
  2. Check the box for Set server as project default and click Finish.
  3. Wait for the server to start and for the comboBoxExample.faces page to display.

When the page displays, the first thing that you may notice is that the table is empty. However, the Combo Box is showing a city name (Austin). We will address this issue next, but first, notice the other behaviors.

Figure 21. Testing the page
Testing the page
  1. Click the Combo Box to select Chicago as the city.
  2. Click the Combo Box again to select Austin as the city one more time. Notice that the information about Chicago is displayed, instead.
Figure 22. Testing the page: 2
Testing the page
  1. Click the Combo Box again to select Chicago as the city. Notice that the information about Austin is displayed, instead.
Figure 23. Testing the page: 3
Testing the page

Why this behavior?

The data for the largestCityPopulationSB Relational Record List is caching the information to enhance performance. The caching mechanism works in a standard environment when you navigate from one page to another. However, when using Ajax, it causes this behavior.

Turn off caching for the largestCityPopulationSB Relational Record List

Note:
The Relational Record List does not have a property to set or reset the caching. Instead, you need to edit the page code bean to turn it off.

  1. Close the comboBoxExample.faces page by clicking the X on its tab. You will be switched back to the comboBoxExample.jsp view.
  2. Right-click inside the comboBoxExample.jsp page and select Edit Page Code to open the ComboBoxExample.java file.
  3. From the Edit drop-down menu, click Edit > Find/Replace.
  4. For Find, enter List getLargestCityPopulationSB(), and then click Find.
  5. Enter a comment to negate the if (largestCityPopulationSB == null) statement by adding two forward-slash marks: //. This will turn the caching off by forcing the doLargestCityPopulationSBFetchAction() method to run every time. The getLargestCityPopulationSB() should look like Listing 1
Listing 1. Edit the page code to turn off caching
  public List getLargestCityPopulationSB() {
  // if (largestCityPopulationSB == null) {
  doLargestCityPopulationSBFetchAction();
  // }
  return largestCityPopulationSB;
  }
  1. Close the ComboBoxExample.java file.
  2. To save your work, click File > Save All.

Test the page again

  1. Under WeatherForecastProject/WebContent, right-click comboBoxExample.jsp and select Run As > Run on Server.
  2. Wait for the server to start and for the comboBoxExample.faces page to display.
  3. When the page displays, click the Combo Box to select Chicago as the city. Notice that the information about Chicago is actually displayed this time.

Initialize the sessionScope variable

Now that you have resolved the caching issue, let’s address the other issue, which is displaying the information about the city that corresponds to the information shown in the Combo Box at startup.

To initialize the largestCityVar at page startup, we edit the page code for comboBoxExample.jsp and modify the getLargestCitiesSB() method.

The reason for the problem

The Combo Box has largestCityVar as its value, and it gets populated with the values from Largest_City element from the Relational Record List largestCitiesSB. The Relational Record List largestCityPopulationSB that displays the City information has a filter that uses largestCityVar.

The problem is that the session scope variable, largestCityVar, is not being initialized, and it is holding a Null value at the startup of the JSP page. That's why largestCityPopulationSB it is not displaying any information at startup.

Initialize the largestCityVar with the value of the first SDO element for Largest_City:

  1. Close the comboBoxExample.faces page by clicking the X on its tab. You will be switched back to the comboBoxExample.jsp page.
  2. Right-click inside of the comboBoxExample.jsp page, and select Edit Page Code to open the ComboBoxExample.java file.
  3. from the Edit drop-down menu, click Edit > Find/Replace.
  4. For Find, enter List getLargestCitiesSB(), and then click Find.
  5. Add the code from Listing 2 to the method (see Resources to learn more about SDOs and DataObjects):
Listing 2. Initialize the largestCityVar with the value of the first SDO element
     if (largestCitiesSB == null) {
         doLargestCitiesSBFetchAction();
			
         // Add the following code to initialize the "largestCityVar" variable.
        // +++ Start of Added Code
       if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null) {
           // Get the first Object
           DataObject myfirstObject = (DataObject) largestCitiesSB.get(0);
           // Assign the first SDO value for element LARGEST_CITY to the variable.
           getSessionScope().put("largestCityVar", myfirstObject.get("LARGEST_CITY"));
       }
      // +++ end of Added Code
   }
   return largestCitiesSB;
}
  1. Close the comboBoxExample.java.
  2. Click File > Save All again to save your changes.

Test the page once more

  1. Under WeatherForecastProject/WebContent, right-click comboBoxExample.jsp and select Run As > Run on Server.
  2. Wait for the server to start and for the comboBoxExample.faces page to display.

Notice that the information is displayed at startup that corresponds to the Combo Box entry.

  1. Click the Combo Box and select All Cities. Now, you'll see the list of the top 20 cities with their information. That's because the largestCityVar has the % wild card as its value. Therefore, the Where SQL Statement reads: where LARGEST_CITY LIKE %. Also notice the alternating row background color in the table. Close comboBoxExample.faces.

Optional steps

If you want the page to show either the information for a specific city at startup (for example, New York) or for All Cities, you need to initialize largestCityVar with New York, for the first case, or you need to initialize largestCityVar with %, for the second case.

For example, this is the getLargestCitiesSB() code for New York:

// Add the following code to initialize the "largestCityVar" variable.
// +++ Start of Added Code
if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null) 
   {// Assign New York to the variable.
   getSessionScope().put("largestCityVar", "New York");}
// +++ end of Added Code

This is the code for All Cities with the % wild card:

// Add the following code to initialize the "largestCityVar" variable.
// +++ Start of Added Code
if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null) 
   {// Assign % to the variable.
   getSessionScope().put("largestCityVar", "%");}
// +++ end of Added Code
  1. Close the comboBoxExample.jsp page.

Add a Data Tree JSP page to the application

This part of the weather forecast application displays the 10-day forecast for a given city within the state.

In this section, you will complete these seven main steps:

  1. Create a second JSP page using JavaServer™ Faces technology.
  2. Create session scope variables.
  3. Create Relational Record Lists.
  4. Add these controls and Ajax support to the JSP page:
    • Table
    • Input-Hidden components
    • Data Tree
    • Panel Group-Box
    • Tabbed Panel
  5. Turn off the Relational Record List caching
  6. Access the State Details
  7. Deploy and test the weather forecast application.

Create the dataTreeExample.jsp JSP page

First, you will create your second JSP page using Java™Server Faces technology. The page will use a Data Tree to display all of the states and cities in a hierarchical view. It uses the Panels-Tabbed JSF component. The first panel will have a Relational Record List to display the 10-day forecast for the selected city. The second panel will display the details about its State.

To begin, stop the server:

  1. In the Servers view, right-click WebSphere Application Server v6.1 and select Stop.

Important:
The embedded Derby database that is included with Rational Application Developer allows for only one active connection at a time. This limitation does not apply if you are using IBM DB2®, instead. Therefore, when you need to create or modify the Relational Record Lists, you must stop the WebSphere Application Server to relinquish its database connection.

To create the JSP page:

  1. While in the Web perspective, right-click WeatherforecastProject, and then select New > Web Page to start the New Page wizard.
  2. For File Name, enter dataTreeExample.jsp.
  3. Under Basic Templates, select JSP.
  4. Click Options, select JavaServer Faces.
  5. Click Close.
  6. Click Finish.
Figure 24. Create a second JavaServer Page
Creating a second JavaServer Page

The dataTreeExample.jsp file is created under WeatherForecastProject/WebContent. After Rational Application Developer opens the page, you are ready to design this page.

Create sessionScope variables

  1. Create a sessionScope variable called stateVar.
    1. From the Web perspective, click the Page Data tab, which is the lower-left pane, and expand Scripting Variables.
    2. Right-click sessionScope, and then select New > Session Scope Variable.
    3. For Variable name, enter stateVar.
    4. For Type, enter java.lang.String.
    5. Click OK.
  2. Create a second sessionScope variable called cityVar:
    1. Following the same instructions, create another sessionScope variable called cityVar of type java.lang.String.

Create Relational Record Lists

You will create two Relational Record lists.

Create a Relational Record List called stateCitiesSB.

  1. From the Page Data view, which is the lower-left pane in the Web perspective, right-click Relational Records and select New > Relational Record List.
  2. For the name, enter stateCitiesSB.
  3. Click Next.
  4. If you get the Database Authorization window:
    1. Click OK
    2. Click New.
    3. Select Use an existing connection.
    4. Select WeatherForecastDB and click Next.
    5. For User ID, leave it as Weather.
    6. Leave the Password field blank.
    7. Click Next.
  5. Click Finish.
  6. Under Table, scroll down, expand WEATHER, and select STATES.
  7. Click Next.
  8. Click None to deselect the columns. You will notice that only STATE is still selected, because it is the primary key.
  9. Under Tasks, click the link Add another database table through a relationship.
  10. Select WEATHER.STATES <- WEATHER.STATESANDCITIES.
Figure 25. Add another database table through a relationship
Screen capture
  1. Click Finish.
  2. Expand Relation: STATES_STATESANDCITIES > STATESANDCITIES.
  3. Ensure that LARGEST_CITY: String is selected.
  4. Click Finish.
Figure 26. Create the stateCitiesSB Relational Record List
Creating a Relational Record List

Create another Relational Record List called tenDayForecastSB

Note:
This time, you will apply a filter to select only the records that correspond to the selected city and state, as specified by the cityVar and stateVar sessionScope variables.

  1. From the Page Data tab, which is the lower-left pane in the Web perspective, right-click Relational Records and select New > Relational Record List.
  2. Enter tenDayForecastSB for the name.
  3. Click Next.
  4. Under Table, scroll down, expand WEATHER, and select TENDAYFORECAST.
  5. Click Next.
  6. Under Tasks, click Filter results.
  7. Click the plus sign (+).
  8. For Column, select STATE =.
  9. Select Variable. and click the ellipses button (with the 3 dots: ...).
  10. Expand sessionScope and select stateVar.
  11. Click OK.
  12. Click OK again.
  13. Click the + sign again.
  14. For Column, select CITY =.
  15. Select Variable and click the button with the 3 dots.
  16. Expand sessionScope and select cityVar.
  17. Click OK.
  18. Click OK.
  19. Click Close.
  20. Click Finish.
Figure 27. Apply a filter to Relational Record List
Selecting the Relational Record List

Add the components and Ajax support to the JSP page

Add a table to the JSP page:

  1. Use the palette to drag a table onto the page under HTML Tags. Specify these values:
    • Rows: 2
    • Columns: 2
    • Table width: 100%
    • Border width: 0 pixels
  2. Click OK.
  3. In the Properties view for the table, select the table leaf and specify this layout (see Figure 28):
    • Align: Left (Make sure the table leaf is still selected.)
    • Width: 100%
    • Height: 100%
Figure 28. Add a table to the JSP page
Creating a table on the JSP page
  1. In the Properties view for the cell, with the cursor in the top-left cell, specify these values:
    • Horizontal: Left
    • Vertical: Top
    • Width: 20%
    • Wrap lines automatically: Not checked.
  2. Put the cursor in the top-right cell and specify this format:
    • Horizontal: Left
    • Vertical: Top
    • Width: 80%
    • Wrap lines automatically: Not checked.
  3. Click File > Save All to save your work.

Add two Input-Hidden components to the JSP page:

  1. Under Enhanced Faces Components, drag an Input-Hidden component into the bottom-left cell.
  2. Change its ID in Properties to txtState.
  3. Still under Enhanced Faces Components, drag another Input-Hidden component to the bottom-right cell.
  4. Change its ID in Properties to txtCity.

Bind the scripting variables to the Input components

  1. From the Page Data view, expand Scripting Variables > sessionScope.
  2. Drag stateVar onto the txtState.
  3. Drag cityVar onto the txtCity.
  4. Click File > Save All.

Notes:

  • You will use the hidden input components to update the scripting variables, as outlined in the steps that follow.
  • Some components, such as Input-Hidden, are hidden, by default on the palette. To show a hidden component in the palette:
    1. Right-click inside of the Palette view and select Customize.
    2. Clear the Hide check box for each component that you want to display on the palette.

Add a Data Tree to the JSP page

Note:
A Data Tree component shows the cities under each State in a hierarchical list (List of States > State > City).

  1. Under Enhanced Faces Components, drag and drop a Data Tree to the top-left cell.
  2. When you see the dialog box that asks, ";This control requires new project resources. Copy them now?"; click Yes.
  3. From the Data Tree Properties view (Figure 29), with the odc:tree leaf selected, specify these values:
    • Width: 100%
    • Height: 100%

Bind the Relational Record List statesCitiesSB to the Data Tree

  1. From the Page Data tab, expand Relational Records > statesCitiesSB (Service Data Object).
  2. Drag statesCitiesSB (STATES) onto the Data Tree.
Figure 29. Data Tree Properties view
Screen capture of data tree properties view
  1. From the Data Tree Properties view, click the Tree Node List leaf.
  2. Under ";Select the nodes to display," select Root.
  3. For the Label value, enter List of States.
  4. Under "Select the nodes to display," click the + sign to expand the State List node.
  5. Select stateCitiesSB, and make sure that STATE is showing in the Label value.
  6. Expand the stateCitiesSB node.
  7. Check the STATES_STATESANDCITIES node.
  8. From the drop-down menu for the Label value, select LARGEST_CITIES.
Figure 30. Data Tree Node List
Screen capture of selecting values
  1. Click File > Save All to save your work.

Figure 31 shows how the Data Tree should look.

Figure 31. Data Tree hierarchy
Screen capture of the Data Tree

In Figure 31, List of States is the Root node. The stateCitiesSB node holds the names of the States, and the STATES_STATESANDCITIES node holds the names of the Largest Cities at run time. It corresponds to the Relational Record List stateCitiesSB hierarchy shown in Figure 32.

Figure 32. Relational Record List stateCitiesSB hierarchy
Screen capture of Relational Record List stateCitiesSB hierarchy

When you click on a city name in the Data Tree, you need to capture its corresponding State (the parent node), because both the State and City are accessed as parameters to update the tenDayForecastSB filter of the Relational Record List by using the variables stateVar and cityVar.

Note:
To get the parent node, you will add another attribute to the STATES_STATESANDCITIES node by using the odc:treeColumnData tag.

Add an attribute to the Data Tree

  1. From the JSP page, select the Data Tree.
  2. From the Properties view, make sure that <odc:tree> is selected.
  3. Check Display tree as a table.
  4. Add these two labels:
    • Label: Column 1, Width: 20
    • Label: Column 2, Width: 20
  5. In the Properties view, click the Tree Node List leaf.
  6. Under "Select the nodes to display," expand List of States > stateCitiesSB.
  7. Select the STATES_STATESANDCITIES node (Figure 33).
  8. Under "Column data," click Add to add an attribute.
  9. Select STATE, and then press the Tab key.
Figure 33. Add State as an attribute
Screen capture of properties view
  1. From the Properties view, click <odc:tree> again.
  2. Uncheck Display tree as a table.
  3. Click Yes in response to this message: "Do you really want to remove the TreeTable tag and its content from this table?"

Note:
By unchecking "Display tree as a table," the Column data under the Properties view for the STATES_STATESANDCITIES node will no longer show STATE. However, the attribute tag is hidden and will hold the STATE value. It will be accessible through JavaScript in the Tree node event handlers (in this example, it will be the onhighlight event), as you will see later.

You can verify that the attribute been added by switching to the JSP Source tab. The screen capture in Figure 34 shows that this code was added:

<odc:treeColumnData id=":columnData1": attributeName=":STATE":></odc.treeColumnData>
Figure 34. Verification that the code was added
Verifying the attributes added
  1. Click File > Save All to save your work.

Add a Panel-Group Box to the JSP page

  1. Drag a Panel-Group box into the top-right cell. This is the area of the page that will be updated by the Ajax request.
  2. For Type, select Box, and click OK.

Adjust the Panel Properties

  1. Select the panel and switch to the Properties view.
  2. Make sure that hx:panelBox is selected, and specify these values:
    • Width: 100%
    • Height: 100%
    • Vertical: Top
    • Horizontal: Left

Add Ajax support to the panel

  1. Select the panel, and switch to the Properties view (Figure 35).
  2. Make sure that hx:panelBox is selected.
  3. Select the Ajax leaf for the hx:panelBox.
  4. Click the Allow Ajax updates check box.
  5. Click Submit as the Ajax request type.
Figure 35. Properties view
Screen capture of the properties view
  1. Click File > Save All.

Initiate the Ajax request

Use the onhighlight event for the STATES_STATESANDCITIES node to initiate the Ajax request:

  1. From the Data Tree, select the STATES_STATESANDCITIES node.
  2. Switch to the Quick Edit view (next to the Properties view).
  3. In the list of events on the left side, select the onhighlight event.
  4. Click the Use predefined behavior check box.
  5. Select the action to Invoke Ajax behavior on the specific tag.
  6. Select box1 as the target.
  7. For Target, replace box1 with form1:box1 and press the Tab key.

Reason for this action:
In Version 7.0 of Rational Application Developer, you must fully qualify the ID of the Panel-Group Box (rather than "box1" use "form1:box1"). Otherwise, the Ajax Submit request would not work correctly.

  1. Click File > Save All.
  2. Click anywhere inside of the onhighlight event.
  3. Add the code shown in Listing 3
Listing 3. Code for onhighlight event
  try {
  var eobj = thisEvent.eobject;
  var obj = document.getElementById("form1:txtCity");
  var obj2 = document.getElementById("form1:txtSTATE");
  if (obj && obj2) {
  obj.value= eobj.eGet('LARGEST_CITY');
  obj2.value = eobj.eGet('STATE');
  } 
  }
  catch (e) {
  alert(e+": "+e.message); 
  }
  1. Click File > Save All.

The onhighlight event should look like Figure 36.

Figure 36. Code for the onhighlight event
Screen capture of the code

The onhighlight event is triggered when the user clicks the tree node. The JavaScript assigns its value (in this example, the Largest City name), along with the hidden attribute value associated with the node (in this example, the associated State name) to the two input text components: txtState and txtCity, respectively. The sessionScope variables stateVar and cityVar are updated accordingly.

  1. Switch to the JSP Source tab and verify the code (also see the screen output in Figure 37):
            <odc:treeNodeAttr
            className="commonj.sdo.DataObject(DynWDO`stateCitiesSB`STATEANDCITIES)"
            id="treenodeattr3" attributeName="LARGEST_CITY">
            <odc:behavior event="onhighlight" id="behavior1"
            	behaviorAction="get" targetAction="form1:box1"
            	onActionFunction="return func_1(this event);"></odc:behavior>
Figure 37. Workaround for the odc:behavior tag
Adding the code

Add a Panels-Tabbed component to the JSP page with two tabs

  1. Under the Enhanced Faces Components, from the Palette, drag a Panels-Tabbed component onto the Panel Box (box1) on the JSP page.
  2. Click Tabbed Panel to select it, and then click the Properties view.
  3. With the odc:tabbedPanel selected, enter these values;
    • Width: 100%
    • Height: 100%
  4. Deselect Show Next and Back buttons.
Figure 38. Panels-Tabbed Properties view
Screen capture of panels
  1. Click the Panel List leaf, and modify the labels for bfpanel1 and bfpanel2 to say Ten Day Forecast and State Details, respectively (see Figure 39).
Figure 39. Modify bfpanel1 and bfpanel2 in the Panel List leaf
Modifying the labels

Add the Relational Record List tenDayForecastSB to the Ten Day Forecast tab

  1. On the JSP page, click the Ten Day Forecast tab to select it.
  2. From the Page Data tab, expand Relational Records > tenDayForecastSB (Service Data Object).
  3. Drag tenDayForecastSB (TENDAYFORECAST) onto the Panels-Tabbed area.
  4. Deselect TENDAYIDX.
  5. Edit the labels (by clicking inside each label) as in Table 2 and also shown in Figure 40.
Table 2. Edit labels in this order
Column NameLabelControl Type
STATEStateOutput Field
CITYCityOutput Field
FORECASTDATEForecast DateOutput Field
FORECASTForecastOutput Field
TEMPERATURETemperatureOutput Field
PRECIPITATIONPrecipitation %Output Field

Figure 40. Edited labels
Editing the labels
  1. Click Finish to close the Configure Data Controls window.

Alternate the background color for each row in the table

  1. Click the leaf Display options.
    • Make sure that Row classes show rowClass1, rowClass2.
    • Remove the columnClass1 entry from Column classes.
  2. Select File > Save All.

Your page should look like the screen capture in Figure 41.

Figure 41. Revised page
Screen capture of the revised page

Turn off caching

As explained in the earlier section, you need to turn off caching to get your updated city choices to display.

Turn off the caching for tenDayForecastSB

  1. Right-click the dataTreeExample.jsp page, and select Edit Page Code to open the dataTreeExample.java file.
  2. From the Edit drop-down menu, click Edit > Find/Replace.
  3. For Find, enter List getTenDayForecastSB(), and then click Find.
  4. Use a comment to negate the if (tenDayForecastSB == null) { statement. This will turn the caching off by forcing the doTenDayForecastSBFetchAction() to run every time. The getTenDayForecastSB() action should then look like Listing 4.
Listing 4. Turn off the caching for tenDayForecastSB
  public List getTenDayForecastSB() {
  // if (tenDayForecastSB == null) {
  doTenDayForecastSBFetchAction();
  // }
  return tenDayForecastSB;
  }
  1. Click Close to close Find/Replace.
  2. Close the DataTreeExample.java.
  3. Save your work by clicking File > Save All.

Test the page

Important:
During the process of designing the JSP page, the Data Tree might lose its configuration. Always ensure that the Tree Node List for the Data Tree reflects what you previously configured, and save your work.

  1. Under WeatherForecastProject/WebContent, right-click dataTreeExample.jsp and select Run As > Run on Server.
  2. If the window to Disconnect ForecastWeatherDB appears, click Finish to close it.
  3. Wait for the server to start and for the dataTreeExample.faces page to display.
  4. Click the Data Tree to expand Alabama.
  5. Click Birmingham. The data table displays the 10-day forecast for that city.

Access the State Details

We will populate the State Details tab with details about the selected State

You will perform these two primary tasks:

  • Create a Relational Record List that includes both STATES and STATESANDCITIES tables. You will filter the information based on the selected State.
  • Add Java code to the dataTreeExample.jsp page code to access the Relational Record List elements.

Tip:
This article shows you how to programmatically access data elements from a Relational Record List. However, you can use a Relational Record as an alternative to display the information without any coding.

  1. To begin, stop the server: In the Servers view, right-click WebSphere Application Server v6.1 and select Stop.
  2. Next, create a Relational Record List called stateDetailsSB.
    1. From the Page Data view, which is the lower-left pane in the Web perspective, right-click Relational Records and select New > Relational Record List.
    2. For the name, enter stateDetailsSB.
    3. Click Next.
    4. For User ID, leave it as Weather.
    5. Leave the Password blank.
    6. Click OK.
    7. Under Table, scroll down, expand WEATHER, and select STATES.
    8. Click Next.
    9. Under Tasks, click the link for Add another database table through a relationship.
    10. Select WEATHER.STATES <- WEATHER.STATESANDCITIES (see Figure 42).
Figure 42. Choose a relationship
Adding another database table through a relationship
  1. Click Next.
  2. Then click Finish.

Note:
Because you did not explicitly name the relationship in this example, Rational Application Developer automatically provided the name: STATES_STATESANDCITIES. If you want to rename this relationship, simply select it, right-click and from the drop-down menu, select Rename Relationship. The name of the relationship will appear in the stateDetailsSB.xml file under the relationship tag name=:

<relationships childKey=";//@tables.1/@foreignKeys.0"; 
  parentKey=";//@tables.0/@primaryKey"; name=";STATES_STATESANDCITIES"; 
  exclusive=";false";/>

You can find the stateDetailsSB.xml file under WebContent/WEB-INF/wdo.

  1. Now, under Tasks, click Filter results.
  2. Select STATES and click the + sign.
  3. Under Task, click Filter results.
  4. Click the + sign.
  5. Select STATES and, from the drop-down menu for Column, select the equal sign (=).
  6. Select Variable and click the button with the 3 dots (. . . ).
  7. Expand sessionScope and select stateVar.
  8. Click OK.
  9. Click OK again.
  10. Click Close.
  11. Then click Finish.

Add the Java code to dataTreeExample.jsp page

  1. Right-click the dataTreeExample.jsp page, and select Edit Page Code to open the dataTreeExample.java file.
  2. Enter the code shown in Listing 5 at the end of the getSDOConnectionWrapper()method.
Listing 5. Code to add to the dataTreeExample.jsp page
:
:
:
		return SDOConnectionWrapper;
	}
:
:

// Add this code below	
public String getStateInfo() {

String stateInfo = "";

List stateList = getStateDetailsSB();
if (stateList.size() != 0) {
try {
DataObject graph = 
getStateDetailsSBMediator().getGraph(getStateDetailsSBParameters());
DataObject states = graph.getDataObject("STATES.0");
String strState = states.getString("STATE");
String strStateNickName = states.getString("STATE_NICKNAME");
String strCapital = states.getString("CAPITAL");
String strEstimatedPoplulation = states.getString("ESTIMATED_2006_POPULATION");
String strLargestCity = 
states.getDataObject("STATES_STATESANDCITIES").getString("LARGEST_CITY");
				
stateInfo = "The nick name for the state of " + strState + " is " + strStateNickName + ". 
The estimated 2006 population is " + strEstimatedPoplulation + ". 
Its largest city is " + strLargestCity + " and its capital is " + strCapital + ".";

} catch (Throwable e) {
	logException(e);
	}
}
return stateInfo;
}
  1. Save your work: File > Save All.

Notes:

  • The code above is an example showing you how to access a DataObject within another DataObject. The Relational Record List stateDetailsSB has a filter that selects records only belonging to the specified state defined in stateVar. The code getStateInfo() accesses the DataObject STATES using the code "DataObject states = graph.getDataObject("STATES.0");". This statement provides access to the various elements in the STATES (for example, CAPITAL) by calling states.getString("CAPITAL"). However, you also need to access the name of the largest city for the selected state. It happened to be that "LARGEST_CITY" is an element that belongs to STATESANDCITIES.
  • DataObjects may contain other DataOjbects. In this example, the stateDetailsSB contains both STATES and STATESANDCITIES that are related through STATES_STATESANDCITIES relationship. The code ";states.getDataObject(";STATES_STATESANDCITIES";).getString(";LARGEST_CITY";));"; accesses ";LARGEST_CITY";, which is an element in the second DataObject.
  • Accessing the elements is case-sensitive. To view the stateDetailsSB elements, open the stateDetailsSB.xml file under WebContent/WEB-INF/wdo.

Turn off caching for Relational Record List stateDetailsSB

  1. From the Edit drop-down menu on the JSP page, click Edit > Find/Replace.
  2. For Find, enter List getStateDetailsSB(), and then click Find.
  3. Use a comment to negate the if (stateDetailsSB == null) { statement. This will turn the caching off by forcing the doStateDetailsSBFetchAction() to run every time.

The getStateDetailsSB() action should now look like Listing 6.

Listing 6. Edit the page code to turn off caching
public List getStateDetailsSB() {
	//	if (stateDetailsSB == null) {
			doStateDetailsSBFetchAction();
	//	}
		return stateDetailsSB;
}
  1. Click Close to close Find/Replace.
  2. Close the DataTreeExample.java file.
  3. Select File > Save All to save your work.

Add stateInfo to the JSP page

  1. Click the State Detail tab.
  2. From the Page Data view, expand Page Bean.
  3. Drag stateInfo (java.lang.String) onto the State Detail tab.
  4. Under Label, delete StateInfo (make it blank).
Figure 43. Add stateInfo to the JSP page
Add stateInfo to the JSP page
  1. Click Finish.
  2. Click File > Save All.

Test the page again

Note:
As mentioned previously, during the process of designing the JSP page, the Data Tree might lose its configuration. Always ensure that the Tree Node List for the Data Tree reflects what configured previously, and save your work.

  1. Under WeatherForecastProject/WebContent, right-click dataTreeExample.jsp, and select Run As > Run on Server.
  2. Click Finish to disconnect WeatherForecastDB.
  3. Wait for the server to start and for the dataTreeExample.faces page to display.

When the page is displayed:

  1. Click the Data Tree to select a city. Notice that the 10-day forecast for the city is now displayed.
  2. Click the State Details tab. You will see the state details, including the name of the largest city.

Summary

This article explained how to use various JSF components in an Ajax environment. By following this step-by-step exercise and demonstration, you have learned how to design an application that uses Combo Box, Data Tree, Relational Record Lists or SDOs, Panels-Box, and Panels-Tabbed components. You also learned a technique for accessing elements from a DataObject that contains another DataObject.

See Resources to learn more about the various technologies used in this article.

Acknowledgment

The author thanks Yury Kats for his technical input. Yury is a developer on the IBM Rational Application Developer team, working with JSF implementation, components, and tooling. He is the author of several developerWorks articles.


Download

DescriptionNameSize
Database used in this exampleSolutionWeatherForecastAjaxProject.zip6028KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Rational software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=295812
ArticleTitle=How to use JavaServer Faces components with Ajax in IBM Rational Application Developer
publish-date=03252008