Skip Headers
Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3)
B25386-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

6.2 Using Attributes to Create Text Fields

To create text fields, you bind ADF Faces text UI components to attributes on a data control using an attribute binding. JDeveloper allows you to do this declaratively without the need to write any code. Additionally, JDeveloper provides a complete WYSIWYG development environment for your JSF pages, meaning you can design most aspects of your pages without needing to look at the code.

6.2.1 How to Use the Data Control Palette to Create a Text Field

To create a text field that can display or update an attribute, you must bind the UI component to the attribute using a data control. JDeveloper allows you to do this declaratively by dragging and dropping an attribute of a collection from the Data Control Palette.

To create a bound text field:

  1. From the Data Control Palette, select an attribute for a collection (for a description of which icon represents attributes and other objects in the Data Control Palette, see Section 5.2.1, "What You See on the Data Control Palette").

    For example, Figure 6-1 shows the problemDescription attribute under the ServiceRequest collection for the findAllServiceRequest() method of the SRPublicFacade data control in the SRDemo application. This is the attribute to drop to display the problem description for a service request.

    Figure 6-1 Attributes Associated with a Returned Object in the Data Control Palette

    Attributes for service requests below the collection

    If you wish to create input text fields used to collect data, you can use either a custom method or one of the data control's built-in creation methods. For procedures, see Section 10.7, "Creating an Input Form for a New Record".

  2. Drag the attribute onto the page, and from the context menu choose the type of widget to display or collect the attribute value. For an attribute, you are given the following choices:

    • Texts

      • ADF Output Text with a Label: Creates a panelLabelAndMessage component that holds an ADF Faces outputText component. The label attribute on this component is populated.

      • ADF Output Text: Creates an ADF Faces outputText component. The label attribute is not populated.

      • ADF Input Text with a Label: Creates an ADF Faces inputText component with a validator. The label attribute is populated.

      • ADF Input Text: Creates an ADF Faces inputText component with a validator. The label attribute is not populated.

      • ADF Label: An ADF Faces outputLabel component.

    • Single selections

      These widgets display lists. For the purposes of this chapter, only the text widgets will be discussed. To learn about lists and their bindings, see Section 11.7, "Creating Databound Dropdown Lists".

6.2.2 What Happens When You Use the Data Control Palette to Create a Text Field

When you drag an attribute onto a JSF page and drop it as a UI component, among other things, a page definition file is created for the page (if one does not already exist), using the name of the JSF page and appending PageDef as the name of the page definition file. For example, the page definition file for the SREdit page is SREditPageDef.xml. For a complete account of what happens when you drag an attribute onto a page, see Section 5.2.3, "What Happens When You Create a Component From the Data Control Palette". Bindings for the iterators and methods are created and added to the page definition file if they do not already exist, as are the bindings for each attribute. Additionally, the necessary code for the UI component is added to the JSF page.

6.2.2.1 Creating and Using Iterator Bindings

Whenever you create UI components on a page by dropping an item that is part of a collection from the Data Control Palette (or you drop the whole collection as a form or table), JDeveloper creates a method iterator binding. A method iterator binding holds references to the data collection and iterates over its data objects. It also manages currency and state for the data objects in the collection. An iterator binding does not actually access the data. Instead, it simply exposes the object that can access the data, and it specifies the current data object in the collection. Other bindings then refer to the iterator binding in order to return data for the current object or to perform an action on the object's data.


Tip:

There is one iterator created for each collection. This means that when you drop two attributes from the same collection (or drop the collection twice), they use the same iterator. This is fine, unless you need the iterator to behave differently for the different components.

For example, if you drop the problemDescription attribute under the ServiceRequest collection for the findAllServiceRequest() method, JDeveloper creates a method iterator binding for the returned ServiceRequest collection.

The iterator binding's rangeSize attribute determines how many records will be retrieved from the database each time the iterator binding is accessed. By default, it is set to 10. For more information about using this attribute, see Section 6.4.2.2, "Iterator RangeSize Attribute". Example 6-1 shows the method iterator binding created when you drop an attribute from the ServiceRequest collection for the findAllServiceRequest() method.

Example 6-1 Page Definition Code for a Method Iterator Binding When You Drop an Attribute from a Method Return Collection

<executables>
    <methodIterator id="findAllServiceRequestIter"
                    Binds="findAllServiceRequest.result"
                    DataControl="SRPublicFacade" RangeSize="10"
                    BeanClass="oracle.srdemo.model.entities.ServiceRequest"/>
</executables>

For information regarding the iterator binding element attributes, see Section A.2.2, "Oracle ADF Data Binding Files".

JDeveloper also creates an action binding for the findAllServiceRequest method used to return the collection. Note that this action binding is created as a binding element and not an executable element. Example 6-2 shows the action binding created when you drop an attribute of the ServiceRequest collection for the findAllServiceRequest() method.

Example 6-2 Page Definition code for an Action Binding Used by the Iterator

  <bindings>
    <methodAction id="findAllServiceRequest"
                  InstanceName=""SRPublicFacade.dataProvider"
                  DataControl="SRPublicFacade"
                  MethodName="findAllServiceRequest" RequiresUpdateModel="true"
                  Action="999"
                  ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
                            dataProvider_findAllServiceRequest_result"/>

This metadata allows the ADF binding container to access the attribute by allowing the iterator to access the result property on the associated method binding. Because the iterator is an executable, it is created when the page is loaded, and thus causes the method referenced in the method binding to execute.

In Example 6-1, the iterator is bound to the result property of the findAllServiceRequest method binding. This means that the iterator will manage all the returned service requests, including determining the current service request or range of service requests.

For information regarding the action binding element attributes, see Section A.2.2, "Oracle ADF Data Binding Files".

6.2.2.2 Creating and Using Value Bindings

When you drop an attribute from the Data Control Palette, JDeveloper creates an attribute binding that is used to bind the UI component to the attribute's value. This type of binding presents the value of an attribute for a single object in the collection. Value bindings can be used to both display and collect attribute values.

For example, if you drop the problemDescription attribute under the ServiceRequest collection for the findAllServiceRequest() method as an ADF Output Text w/Label widget onto the SREdit page, JDeveloper creates an attribute binding for the problemDescription attribute. Note that the attribute value references the findAllServiceRequestIter iterator. This allows the binding to access the attribute value of the current record. Example 6-3 shows the attribute binding for problemDescription created when you drop the ServiceRequest collection for the findAllServiceRequest() method.

Example 6-3 Page Definition Code for an Attribute Binding

 <bindings>
    ...
    <attributeValues id="ServiceRequestproblemDescription"
                     IterBinding="findAllServiceRequestIter">
      <AttrNames>
        <Item Value="problemDescription"/>
      </AttrNames>
    </attributeValues>
  </bindings>

For information regarding the attribute binding element attributes, see Section A.2.2, "Oracle ADF Data Binding Files".

6.2.2.3 Using EL Expressions to Bind UI Components

When you create a text field by dropping an attribute from the Data Control Palette, JDeveloper creates the UI component associated with the widget dropped by writing the corresponding code to the JSF page.

For example, when you drop the problemDescription attribute as an Output Text w/Label widget, JDeveloper creates an EL expression that binds the panelLabelAndMessage label's attribute to the label property of the problemDescription binding. It creates another expression that binds the panelLabelAndMessage value attribute to the inputValue property of the problemDescription binding, which in turn is the value of the problemDescription attribute. For more information about binding object properties, see Section A.2.2, "Oracle ADF Data Binding Files".

Example 6-4 shows the code generated on the JSF page when you drop an attribute as an Output Text w/Label widget.

Example 6-4 JSF Page Code for an Attribute Dropped as an Output Text w/Label

<af:panelLabelAndMessage  
         label="#{bindings.ServiceRequestproblemDescription.label}">
    <af:outputText
         value="#{bindings.problemDescription.inputValue}"/>
</af:panelLabelAndMessage>

6.2.2.4 The JSF and ADF Lifecycles

When a page is submitted and a new page requested, the application invokes both the JSF lifecycle and the ADF lifecycle. The JSF lifecycle handles the components at the view layer, while the ADF lifecycle handles the data at the model layer.

Specifically, the JSF lifecycle handles the submission of values on the page, validation for components, navigation, and displaying the components on the resulting page and saving and restoring state. The JSF lifecycle phases use a UI component tree to manage the display of the faces components. This tree is a runtime representation of a JSF page: each UI component tag in a page corresponds to a UI Component instance in the tree. The FacesServlet object manages the request processing lifecycle in JSF applications. FacesServlet creates an object called FacesContext, which contains the information necessary for request processing, and invokes an object that executes the lifecycle.

The ADF lifecycle handles preparing and updating the data model, validating the data at the model layer, and executing methods on the business layer. The ADF lifecycle uses the binding container to manage the collection and display of data, which pools the data and stores it locally before rendering the page. By avoiding additional round trips to the database before a web page is rendered, the lifecycle improves application performance during the rendering process.

The lifecycles are divided into phases. For the two lifecycles to work together, the ADF lifecycle phases are integrated with the JSF lifecycle phases using the JSF event listener mechanism. The ADF lifecycle listens for phase events using the ADF phase listener, which allows the appropriate ADF phases to be executed before or after the appropriate JSF phases.

When an ADF Faces component bound to an ADF data control is inserted into a JSF page for the first time, JDeveloper adds the ADF PhaseListener to faces-config.xml. Example 6-5 shows the ADF PhaseListener configuration in faces-config.xml.

Example 6-5 Registering the ADF PhaseListener in faces-config.xml

<faces-config xmlns="http://java.sun.com/JSF/Configuration">
  ...
<lifecycle>
  <phase-listener>
    oracle.adf.controller.faces.lifecycle.ADFPhaseListener
  </phase-listener>
</lifecycle>
  ...
</faces-config>

Figure 6-2 shows how the JSF and ADF phases integrate in the lifecycle.

Figure 6-2 The Lifecycle of a Page Request in an ADF Application Using ADF Faces Components

The ADF and JSF phases work together

In a JSF application that uses the ADF Model layer, the lifecycle is as follows:

  • Restore View: The URL for the requested page is passed to the bindingContext, which finds the page definition that matches the URL. The component tree of the requested page is newly built or restored. All the component tags, event handlers, converters, and validators on the submitted page have access to the FacesContext instance. If it's a new empty tree (that is, there is no data from the submitted page), the lifecycle proceeds directly to the Render Response phase. Otherwise, the Restore View phase issues an event which the Initialize Context phase of the ADF Model layer lifecycle listens for and then executes.

    For example, for a page that contains an inputText UI component bound to the problemDescription attribute of a ServiceRequest returned collection, when the URL is passed in, the page definition is exposed. The UI component is then built. If data is to be displayed, the Initialize Context phase executes. Otherwise, the lifecycle jumps to the Render Response phase.

  • Initialize Context: The page definition file is used to create the bindingContainer object, which is the runtime representation of the page definition for the requested page. The Context class used to persist information throughout the ADF lifecycle phases is instantiated and initialized.

  • Prepare Model: The binding container is refreshed, which sets any page parameters contained in the page definition. Any entries in the executables section of the page definition are used to invoke the corresponding methods in the order they appear, depending on the value of the Refresh and RefreshCondition attributes. If Refresh is set to prepareModel, or if no value is supplied (meaning it uses the default, ifneeded), then the RefreshCondition attribute value is evaluated. If no RefreshCondition value exists, the executable is invoked. If a value for RefreshCondition exists, then that value is evaluated, and if the return value of the evaluation is true, then the executable is invoked. If the value evaluates to false, the executable is not invoked. The default value always enforces execution.


    Note:

    If you want to use the #{adfFacesContext.postback} expression in a RefreshCondition of an executable, you must set the Refresh property to either prepareRender or prepareRenderIfNeeded.

    For details about the refresh attribute, see Section A.7.1, "PageDef.xml Syntax". If the incoming request contains no POST data or query parameters, then the lifecycle forwards to the Render Response phase.

    In the problem description example, the bindingContainer invokes the findAllServiceRequestIter method iterator, which in turn invokes the findAllServiceRequest method that returns the ServiceRequest collection. The iterator then iterates over the data and makes the data for the first found record available to the UI component by placing it in the binding container. Because there is a binding for the problemDescription attribute in the page definition that can access the value from the iterator (see Example 6-3), and since the UI component is bound to the problemDescription binding using an EL expression (#{bindings.problemDescription.inputValue}), that data is displayed by that component.

  • Apply Request Values: Each component in the tree extracts new values from the request parameters (using its decode method) and stores it locally. Most associated events are queued for later processing. If a component has its immediate attribute set to true, then the validation, conversion, and events associated with the component are processed during this phase. For more information about validation and conversion, see Chapter 12, "Using Validation and Conversion".

    In the example, if a user enters a new value into the inputText component, that value is stored locally using the setSubmittedValue method on the inputText component.

  • Process Validations: Local values of components are converted and validated. If there are errors, the lifecycle jumps to the Render Response phase. At the end of this phase, new component values are set, any validation or conversion error messages and events are queued on FacesContext, and any valueChange events are delivered.

    For a detailed explanation of this and the next two phases of the lifecycle, see Chapter 12, "Using Validation and Conversion".

  • Update Model Values: The component's validated local values are moved to the model and the local copies are discarded.

  • Validate Model Updates: The updated model is now validated against any validation routines set on the model.

  • Invoke Application: Any action bindings for command components or events are invoked. For a detailed explanation of this and the next two phases of the lifecycle, see Section 9.4, "Creating Navigation Using Dynamic Outcome Values". For a description of action bindings used to invoke business logic, see Chapter 10, "Creating More Complex Pages".

  • Metadata Commit: Changes to runtime metadata are committed. This phase is not used in this release, but will be used in future releases.

  • Initialize Context (only if navigation occurred in the Invoke Application lifecycle): The page definition for the next page is initialized.

  • Prepare Model (only if navigation occurred in the Invoke Application lifecycle): Any page parameters contained in the next page's definition are set. Any entries in the executables section of the page definition are used to invoke the corresponding methods in the order they appear.

  • Prepare Render: The binding container is refreshed to allow for any changes that may have occurred in the Apply Request Values or Validation phases. The prepareRender event is sent to all registered listeners.

  • Render Response: The components in the tree are rendered as the J2EE web container traverses the tags in the page. State information is saved for subsequent requests and the Restore View phase.