32 Using More Complex Databound ADF Faces Components

This chapter describes how to add the ADF Faces Calendar and Carousel components to your pages in the Fusion web application.

This chapter includes the following sections:

32.1 About More Complex Databound ADF Faces Components

ADF Faces calendar and ADF Faces carousel are complex components that you can use to include calendar functions or display rotating images in your application. The ADF Faces calendar displays activities in daily, weekly, monthly, or list views for a given provider. The calendar is configurable to only display some of the views. The calendar includes a toolbar with built-in functionality that allows a user to change the view (between daily, weekly, monthly, or list), go to the previous or next day, week, or month, and return to today. The toolbar is customizable and allows you to choose which buttons and text to display, and you can also add buttons or other components.

The ADF Faces carousel displays images in a revolving loop that the user can select by using the slider or clicking another image. It can be configured to have either a horizontal or vertical orientation. You can use other components in conjunction with the carousel. You can add a toolbar or menu bar, and then add buttons or menu items that allow users to perform actions on the current object.

32.1.1 Complex Databound ADF Faces Components Use Cases and Examples

The ADF Faces calendar can be used whenever you want to add a calendar feature to your application. You will need to have the relevant data in your data store that represents the content provided by the calendar, such as the date, time, title, location, and owner. You can use the familiar patterns of entity objects and view objects to model the data and then use drag and drop from the Data Controls panel to create the calendar.

The carousel component gives the user the ability to view an image from a series of images. The user can see partial views of the images before and after the image being viewed and can scroll through each image in the sequence. The user can do so using a slider or navigation buttons. The carousel is useful for showing objects that require a highly visual presentation. For example, it can be used to display a photographic collection or merchandise in a catalog.

32.1.2 Additional Functionality of Complex Databound ADF Faces Components

You may find it helpful to understand other ADF features before you configure or use the ADF Model layer. Additionally, you may want to read about what you can do with your model layer configurations. Following are links to other functionality that may be of interest.

32.2 Using the ADF Faces Calendar Component

ADF Faces includes a calendar component that displays created activities in daily, weekly, or monthly views. Figure 32-1 shows an ADF Faces calendar in weekly view mode with some sample activities.

Figure 32-1 ADF Faces Calendar

ADF Faces calendar component;

The calendar component also includes the following functionality:

  • A toolbar that allows users to switch between monthly, weekly, daily, and list views.

    Tip:

    When these toolbar buttons are used, attribute values on the calendar are changed. You can configure these values to be persisted so that they remain for a particular user whenever they accesses the calendar. For more information, see Chapter 40, "Allowing User Customizations at Runtime."

  • Configurable start of the week days and start of the day hours. For example, a calendar's week might start on Sunday and the day might show 8:00 am at the top.

  • Configurable styles using skinning keys.

Additionally, you can implement the following functionality using other ADF Faces components and the rich client framework:

  • Popup functionality. Components placed in supported faces that respond to certain events and allow the user to act on activities or the calendar. For example, when a user clicks an activity in the calendar, the CalendarActivityEvent is invoked and any popup component in the ActivityDetail facet is displayed. You might use a dialog component that contains a form where users can view and edit the activity, as shown in Figure 32-2.

    Figure 32-2 Edit Dialog for ActivityDetail Facet

    Form to edit Activity in a popup
  • Drag and drop capability: You can add the calendarDropTarget tag that allows a user to drag an activity to another place on the calendar. You then implement the functionality so that the time is actually changed on the activity and persisted to the data store.

  • Toolbar customization: By default, the toolbar contains buttons that allow the user to switch between the different views, along with previous and next buttons and a button that returns to the current date. The toolbar also displays the current date range (or the date when in day view). You can customize the toolbar by adding facets that contain additional buttons of your choosing.

  • Skinning: The calendar uses skinning keys to determine things like colors and icons used. You can extend the skin to change the appearance of the calendar.

Details for configuring the built-in functionality or for implementing additional functionality can be found in the "Using a Calendar Component" chapter of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

An ADF Faces Calendar component must be bound to a CalendarModel class. This class can be created for you when you use ADF Business Components to manage your calendar's data. For example, say you have data in your data store that represents the details of an activity, such as the date, time, title, location, and owner. When you create an entity object to represent that data, and then a view object to display the data, you can drag and drop the associated collection from the Data Controls panel to create the calendar. JDeveloper will declaratively create the model and bind the view to that model so that the correct data will display when the calendar is launched. However, in order for the model to be created, your entity objects in the data model project with ADF Business Components and your view objects in the same project must contain date-effective attributes. Additionally, the view objects must contain variables that will be used to modify the query to return the correct activities for the given date range.

32.2.1 How to Use the ADF Faces Calendar

Before you can create a calendar on a JSF page, you must first create an entity object with specific attributes that represent attributes on a calendar. You then must create a view object from that entity object, and modify the query to use named bind variables that represent the date range and current time zone to display. This will allow the query to return only the activities that should be displayed in the given view on the calendar.

For example, say you have a database table that represents an activity. It has a column for title, start time, end time, and a reference to a provider object that represents the owner. You would create an entity object and a view object based on that table (ensuring that it meets the requirements, as described in the following steps). To the view object, you would then add named bind variables for the start and end times currently displayed on the calendar, along with the time zone currently in use by the calendar, so that the query returns only those activities that fall within that time range.

Once you add the calendar component to a JSF page, you can configure it, and add further needed functionality.

Before you begin:

It may be helpful to have an understanding of the options that are available to you when you create a calendar. For more information, see Section 32.2, "Using the ADF Faces Calendar Component."

To create an ADF Faces calendar:

  1. Create an entity object based on your data source. The entity object must include the attributes shown in Table 32-1. The attributes do not have to use the names shown in the table; they can be named anything. However, they must be of one of the types noted. You will map these attributes to attributes in the CalendarModel in a later step.

    Table 32-1 Required Attributes for a Calendar

    Attribute Valid Types Description

    Start time

    java.util.Date, java.sql.Date, oracle.jbo.domain.Date, oracle.jbo.domain.TimeStamp

    Start time for the activity

    End time

    java.util.Date, java.sql.Date, oracle.jbo.domain.Date, oracle.jbo.domain.TimeStamp

    End time for the activity

    ID

    String

    Unique ID

    Provider ID

    String

    ID of the provider object that represents the owner of the activity

    Title

    String

    Short description of the activity


    The entity object can also contain the known (but not required) attributes shown in Table 32-2:

    Table 32-2 Optional Attributes for a Calendar

    Attribute Type Description

    Recurring

    String or CalendarActivity.Recurring

    Status of recurrence for the activity. Valid values are SINGLE (does not recur), RECURRING, or CHANGED (this activity was part of the recurring activity but has been modified to be different from parent activity).

    Reminder

    String or CalendarActivity.Reminder

    Whether or not the activity has an associated reminder. Valid values are ON or OFF.

    Time Type

    String or CalendarActivity.TimeType

    Type of time associated with the activity. Valid values are ALLDAY and TIME. Activities that have a value of ALLDAY do not have any time associated with them. They are considered to span the entire day. Activities with a value of TIME have a specific time duration.

    Location

    String

    Location of an activity.

    Tags

    Set of Strings or a semicolon separated list of Strings.

    Keywords for the activity.


    Your entity objects can also contain other attributes that the CalendarModel has no knowledge of. You will be able to add these to the model as custom properties in a later step.

    For information on creating entity objects, see Chapter 4, "Creating a Business Domain Layer Using Entity Objects."

  2. Create an associated view object. In the Query page of the overview editor, create named bind variables for the following:

    • A string that represents the time zone

    • A date that represents the start time for the current date range shown on the calendar.

    • A date that represents the end time for the current date range shown on the calendar.

      Tip:

      Dates in an ADF Faces calendar are "half-open," meaning that the calendar will return all activities that start on or after the start time and before (but not on) the end time.

      For more information about creating named bind variables, see Section 5.10, "Working with Bind Variables."

  3. Create an entity object that represents the provider (owner) of activities. The entity object must include the attributes shown in Table 32-3. The attributes do not have to use the names shown in the table; they can be named anything. However, they must be of the type noted. You will map these attributes to attributes in the CalendarProvider class in a later step.

    Table 32-3 Attributes for a CalendarProvider Class

    Attribute Type Description

    Id

    String

    Unique ID.

    Display Name

    String

    The name of the provider that can be displayed in the calendar.


  4. Create a view object for the provider.

  5. Ensure that the new view objects are part of the application module, and if needed, refresh the Data Controls panel.

  6. Create your JSF page, as documented in Section 24.3, "Creating a Web Page."

  7. From the Data Controls panel, drag the collection that represents the view object for the activity created in Step 2 and drop it as a Calendar.

    Tip:

    The Calendar option will display in the context menu only if the view object contains the required attributes documented in Table 32-1 and the bind variables described in Step 2.

  8. Complete the Calendar Bindings dialog to map the bind variables and attributes to the CalendarModel and the CalendarProvider classes. For additional help, click Help or press F1.

  9. By default, the calendar will be read-only and will return only those activities currently in the data store. You will need to configure the calendar and implement additional functionality as described in the "Using a Calendar Component" chapter of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

    For example, to allow creation of a new activity, you might create an input form in a dialog (as described in the "How to Create a Dialog" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework) using the same data control collection used to create the calendar. For more information about creating input forms, see Section 26.6, "Creating an Input Form."

32.2.2 What Happens When You Create a Calendar

When you drop a collection as a calendar, JDeveloper:

  • Defines an iterator binding to the collection of activities, and another iterator binding to the collection of providers.

  • Defines an action binding to the executeWithParams operation on the activities collection. It is this operation that will be invoked to execute the query to return the activities to display. Because the operation requires parameters to determine the date range and time zone, NamedData elements are also created for each of the parameters (created as named bind variables on the view object). For more information about NamedData elements, see Section 28.2.2.2, "Using Parameters in a Method."

  • Defines a calendar binding. This binding contains a node element that represents a row in the collection and maps the data control attributes to the calendar activity's attributes, as defined when using the wizard. The value is the data control attribute and the type is the calendar attribute. For any custom defined attributes, the type will be custom and value will be the data control attribute. Each row (node) is represented by a rowKey, which is the activity ID.

    There is also a providerDefinition element that determines the source and mapping of available providers. This mapping allows the calendar model to filter activities based on the state of the provider (either enabled or disabled).

    Tip:

    To access a custom attribute, use the CalendarActivity.getCustomAttributes() method, passing in the name of the attribute as defined by the value element.

    Example 32-1 shows the page definition code for a calendar.

Example 32-1 Page Definition Code for a Calendar Binding

<executables>
    <iterator Binds="ActivityView1" RangeSize="-1"
              DataControl="AppModuleDataControl" id="ActivityView1Iterator"/>
    <iterator Binds="EmployeesView1" RangeSize="25"
              DataControl="AppModuleDataControl" id="EmployeesView1Iterator"/>
  </executables>
  <bindings>
    <action IterBinding="ActivityView1Iterator" id="ExecuteWithParams"
            RequiresUpdateModel="true" Action="executeWithParams">
      <NamedData NDName="startTime"
                 NDValue="#{bindings.ActivityView1.startDate}"
                 NDType="oracle.jbo.domain.Date"/>
      <NamedData NDName="endTime" NDValue="#{bindings.ActivityView1.endDate}"
                 NDType="oracle.jbo.domain.Date"/>
      <NamedData NDName="timeZone"
                 NDValue="#{bindings.ActivityView1.timeZoneId}"
                 NDType="java.lang.String"/>
    </action>
    <calendar IterBinding="ActivityView1Iterator" id="ActivityView1"
              xmlns="http://xmlns.oracle.com/adf/faces/binding"
              ActionBindingName="ExecuteWithParams">
      <nodeDefinition DefName="model.ActivityView">
        <AttrNames>
          <Item Type="id" Value="Id"/>
          <Item Type="providerId" Value="ProviderId"/>
          <Item Type="title" Value="Title"/>
          <Item Type="startTime" Value="StartTime"/>
          <Item Type="endTime" Value="EndTime"/>
        </AttrNames>
      </nodeDefinition>
      <providerDefinition IterBindingName="EmployeesView1Iterator">
        <AttrNames>
          <Item Type="id" Value="EmployeeId"/>
          <Item Type="displayName" Value="FirstName"/>
        </AttrNames>
      </providerDefinition>
    </calendar>
  </bindings>

JDeveloper inserts code onto the JSF page that binds the calendar value to the CalendarModel class, as shown in Example 32-2.

Example 32-2 JSF Page Code for a Calendar

<af:form>
  <af:calendar value="#{bindings.ActivityView1.calendarModel}"/>
</af:form>

The CalendarModel class uses CalendarActivityDefinition class to access the calendar binding.

32.2.3 What Happens at Runtime: How the Calendar Binding Works

When the calendar is accessed, the executeWithParams operation is invoked, with the value of the startDate and endDate parameters determined by the value of the calendar component's view and activeDay attributes. For example, if the view attribute is set to month and the activeDay is set to the current date (say, February 6, 2009), then the value for the startDate would be February 1, 2009 and the endDate value would be February 28, 2009. By default, the time zone value is taken from the time-zone setting in the trinidad-config.xml file (for more information, see the "Configuration in trinidad-config.xml" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework). Therefore, the query would be restricted to return only activities that fall within that date range.

When the query returns data, because the calendar component is bound to the CalendarModel, the CalendarModel uses the CalendarActivityDefinition class to access the calendar binding class and map the values from the data source to the calendar, using the mappings provided by the binding.

32.3 Using the ADF Faces Carousel Component

You can display images in a revolving carousel, as shown in Figure 32-3. Users can change the image at the front by using either the slider at the bottom or by dragging another image to the front.

Figure 32-3 Carousel Component

Carousel component.

Instead of containing a child carouselItem component for each image to be displayed, and then binding these components to the individual images, the carousel component is bound to a complete collection and repeatedly renders one carouselItem component by stamping the value for each item, similar to the way a tree stamps out each row of data. As each item is stamped, the data for the current item is copied into a property that can be addressed using an EL expression using the carousel component's var attribute. Once the carousel has completed rendering, this property is removed or reverted back to its previous value. Carousels contain a nodeStamp facet, which is a holder for the carouselItem component used to display the text and short description for each item, and is also the parent component to the image displayed for each item. For more information about the carousel component, see the "Displaying Images in a Carousel" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

32.3.1 How to Create a Databound Carousel Component

When using a carousel component in a Fusion web application, you create the component using the Data Controls Panel. You also use a managed bean to handle the carousel spin event and for other logic you may need to display your items.

Before you begin:

It may be helpful to have an understanding of the options that are available to you when you create a calendar. For more information, see Section 32.3, "Using the ADF Faces Carousel Component."

You will need to complete these tasks:

  1. Create a view object for the collection to be displayed in the carousel.

  2. Define the view object with the following minimum set of attributes:

    • Title, which will be displayed below the image in the carousel

    • Short description used for text displayed when the user mouses over the image

To create a databound carousel component:

  1. From the Data Controls panel, drag the collection for the view object on to the page and select Carousel from the context menu.

  2. In the Property Inspector, in the Behavior section, bind the CarouselSpinListener to a handler method that handles the spinning of the carousel when you need logic to be executed when the carousel spin is executed. Example 32-3 shows the handler methods that might be used to handle the display of product images for the Products view object used to create the carousel:

    Example 32-3 Handler for the CarouselSpinEvent

    public void handleCarouselSpin(CarouselSpinEvent event)
    {
      RichCarousel carousel = getCarousel();
      carousel.setRowKey(event.getNewItemKey());
      detailNodeItem = (JUCtrlHierNodeBinding)carousel.getRowData();
    }
    public JUCtrlHierNodeBinding getDetailNodeItem()
    {
    //   Get the initial item
      if(detailNodeItem == null)
      {
        RichCarousel carousel = getCarousel();
        
        Object oldKey = carousel.getRowKey();
        try
          {
             Object key = carousel.getCurrentItemKey();
              getCarousel().setRowKey(key);
              detailNodeItem = (JUCtrlHierNodeBinding)carousel.getRowData();
           }
        finally
         {
           carousel.setRowKey(oldKey);
          }
        }
         
      return detailNodeItem;
    }
       
    
  3. In the Advanced section of the Property Inspector, click the dropdown menu for the Bindings attribute and select Edit. In the Edit Property: Binding dialog, select the managed bean used in Step 2. Create a new property called carousel. This will allow the handler methods to access the carousel object.

  4. In the Structure window, expand the carousel component and the nodeStamp facet, then select the carouselItem component.

  5. Bind the CarouselItem component's text attribute to the associated property in the data model using the variable value set on the carousel's var attribute, which by default is set to item. So the value of the carouselItem's text attribute would be item.title (given that title is the property used to access the text used for the carousel items on the data model).

    If you were using the Products view object, the value would be #{item.ProductName}.

  6. In the Advanced section of the Property Inspector, click the dropdown menu for the Bindings attribute and select Edit. In the Edit Property: Binding dialog, select the managed bean used in Step 2. Create a new property called carouselItem.

  7. In the ADF Faces page of the Component Palette, from the Common Components panel, drag an Image and drop it as a child to the carouselItem.

    In the Insert Image dialog, enter the path to the source for the images, being sure to use the variable for the item in the carousel. For example, the path to the image files for the products would normally be:

    /imageservlet?detail=#{Products.ProductId}
    

    For an image in the carousel, you would use:

    /imageservlet?detail=#{item.ProductId}
    

    For information about setting other attributes of the carousel and carouselItem components, see the "How to Create a Carousel" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

  8. If you want to provide additional information about the items in the carousel, you can drag and drop the same view object onto the page (for example, as a form). For the components in the form to redisplay the information for the current item displayed once the carousel is spun, you need to set the partialTrigger attribute of the component containing the form to the carousel component's ID.

    For example, the form that displays the information for each item in Figure 32-3 is contained in a panelBox component.The partialTrigger attribute for the panelBox component is set to c1, which is the carousel component's ID. This means that whenever the carouselItem invokes the CarouselSpinEvent, the panelBox will be refreshed, causing it to display information about the item that was just made current. For more information about partial page rendering and the partialTriggers attribute, see the "Rerendering Partial Page Content" chapter of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

    Example 32-4 shows the page code for the carousel displayed in Figure 32-3.

    Example 32-4 Partial Trigger Updates the Form to Match the Displayed Carousel Item

    <af:carousel
            currentItemKey="#{bindings.Products.treeModel.rootCurrencyRowKey}"
      value="#{bindings.Products.treeModel}" var="item"
      id="c1"
     carouselSpinListener="#{carBean.handleCarouselSpin}">
       <f:facet name="nodeStamp">
         <af:carouselItem id="ci1" text="#{item.ProductName}"
                          binding="#{carBean.carouselItem}">
           <af:image source="/imageservlet?detail=#{item.ProductId}"
                     id="i1"/>
         </af:carouselItem>
       </f:facet>
     </af:carousel>
     <af:panelBox text="PanelBox1" id="pb1" partialTriggers="c1">
       <af:panelFormLayout id="pfl1">
         <af:panelLabelAndMessage label="#{bindings.ProductName.hints.label}"
                                  id="plam2">
           <af:outputText value="#{bindings.ProductName.inputValue}"
                          id="ot4"/>
         </af:panelLabelAndMessage>
    .
    .
    .
    </af:panelBox>
    

32.3.2 What Happens When You Create a Carousel

When you drop a collection from the Data Controls panel as a carousel, a tree value binding is created. A tree consists of a hierarchy of nodes, where each subnode is a branch off a higher-level node.

The tree binding iterates over the data exposed by the iterator binding. The carousel wraps the result set from the iterator binding in a treeModel object, which is an extension of the collectionModel. The collectionModel allows each item in the collection to be available within the carousel component using the var attribute. For more information about the tree binding, see Section 27.2.2.1, "Iterator and Value Bindings for Tables."

JDeveloper adds both a carousel component and it's child carouselItem component onto the page, as shown in Example 32-5.

Example 32-5 Page Code for a Carousel Component

<af:carousel
        currentItemKey="#{bindings.Products.treeModel.rootCurrencyRowKey}"
        value="#{bindings.Products.treeModel}" var="item"
        id="c1"
        carouselSpinListener="#{carBean.handleCarouselSpin}">
   <f:facet name="nodeStamp">
     <af:carouselItem id="ci1" text="#{item.ProductName}"/>
   </f:facet>
 </af:carousel>

The carousel value is bound to the treeModel for the associated collection, and the currentItemKey attribute of the carousel is bound to the rootCurrencyRowKey of the binding object. In this example, the carousel iterates over the items in the Products iterator binding. The iterator binding binds to a rowKeySet that keeps track of the current product. By default, the currentItemKey attribute of the carousel is bound to the rootCurrencyRowKey of the binding object, which causes the product currently displayed at the front of the carousel to be the root and the current item. The carouselItem component accesses the current data object for the current item presented to the carousel tag using the item variable.