Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g (10.1.3.1.0)

Part Number B25947-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

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

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

13.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 12.2.1, "How to Understand the Items on the Data Control Palette").

    For example, Figure 13-1 shows the ProblemDescription attribute under the ServiceRequests collection of the SRService data control in the SRDemo application. This is the attribute to drop to display or enter the problem description for a service request.

    Figure 13-1 Attributes Associated with a Collection in the Data Control Palette

    Attributes for service requests below the collection
  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 the panelLabelAndMessage component is populated.

      • ADF Output Text: Creates an ADF Faces outputText component. No label is created.

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


        Tip:

        For more information about validators, see Chapter 20, "Using Validation and Conversion".

      • 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 19.7, "Creating Selection Lists".

13.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 including the page's directory name, and appending PageDef as the name of the page definition file. For example, the page definition file for the SREdit page in the ./app/staff subdirectory of the web root is app_staff_SREditPageDef.xml. For a complete account of what happens when you drag an attribute onto a page, see Section 12.2.3, "What Happens When You Use the Data Control Palette". Bindings for the iterator and attributes are created and added to the page definition file. Additionally, the necessary JSPX page code for the UI component is added to the JSF page.

13.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 an iterator binding if it does not already exist. An iterator binding references an iterator for the data collection, which facilities iterating 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 specify 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. Note that the iterator binding is not an iterator. it is a binding to an iterator. In the case of ADF Business Components, the actual iterator is the default row set iterator for the default row set of the view object instance in the application module's data model.


Tip:

There is one iterator binding 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 binding. This is fine, unless you need the binding to behave differently for the different components. In that case, you will need to manually create separate iterator bindings. For procedures and an example, see Section 18.5, "Conditionally Displaying the Results Table on a Search Page".

For example, if you drop the ProblemDescription attribute under the ServiceRequests collection, JDeveloper creates an iterator binding for the ServiceRequests collection.

The iterator binding's rangeSize attribute determines how many records will be available for the page each time the iterator binding is accessed. This attribute gives you a relative set of 1-N rows positioned at some absolute starting location in the overall rowset. By default, it is set to 10. For more information about using this attribute, see Section 13.4.2.2, "Iterator RangeSize Attribute". Example 13-1 shows the iterator binding created when you drop an attribute from the ServiceRequests collection.

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

<executables>
  <iterator id="ServiceRequestsIterator" RangeSize="10"
            Binds="ServiceRequests" DataControl="SRService"/>
</executables>

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

This metadata allows the ADF binding container to access the attribute. Because the iterator binding is an executable, it is invoked when the page is loaded, thereby allowing the iterator to access and iterate over the ServiceRequests collection. This means that the iterator will manage all the service requests in the collection, including determining the current service request or range of service requests.

13.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 current row 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 ServiceRequests collection as an ADF Output Text w/Label widget onto a page, JDeveloper creates an attribute binding for the ProblemDescription attribute. This allows the binding to access the attribute value of the current record. Example 13-2 shows the attribute binding for ProblemDescription created when you drop the attribute from the ServiceRequests collection. Note that the attribute value references the iterator named ServiceRequestsIterator.

Example 13-2 Page Definition Code for an Attribute Binding

<bindings>
    ...
    <attributeValues id="ServiceRequestsProblemDescription"
                     IterBinding="ServiceRequestsIterator">
      <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".

13.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 13-3 shows the code generated on the JSF page when you drop the ProblemDescription attribute as an Output Text w/Label widget.

Example 13-3 JSF Page Code for an Attribute Dropped as an Output Text w/Label

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

If instead you drop the ProblemDescription attribute as an Input Text w/Label widget, JDeveloper creates an inputText component. As Example 13-4 shows, similar to the output text component, the value is bound to the inputValue property of the ProblemDescription binding. Additionally, the following properties are also set:

  • label: bound to the binding's label property.

  • required: bound to the binding's mandatory property. See Section 20.3, "Adding Validation" for more information about this property.

  • columns: bound to the displayWidth property. This determines how wide the text box will be.

Example 13-4 JSF Page Code for an Attribute Dropped as an Input Text w/Label

<af:inputText value="#{bindings.ServiceRequestsProblemDescription.inputValue}"
            label="#{bindings.ServiceRequestsProblemDescription.label}"
            required="#{bindings.ServiceRequestsProblemDescription.mandatory}"
          columns="#{bindings.ServiceRequestsProblemDescription.displayWidth}">
  <af:validator binding="#{bindings.ServiceRequestsProblemDescription.validator}"/>
</af:inputText>

For more information about the properties, see Appendix B, "Reference ADF Binding Properties".

13.2.3 What Happens at Runtime: 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 make data available for easy referencing by the page during the current page request.

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 13-5 shows the ADF PhaseListener configuration in faces-config.xml.

Example 13-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 13-2 shows how the JSF and ADF phases integrate in the lifecycle.

Figure 13-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 LifecycleContext 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 refreshed, depending on the value of the Refresh and RefreshCondition attributes.

    The Refresh and RefreshCondition attributes are used to determine when and whether to invoke an executable. For example, there maybe an executable that should only be invoked under certain conditions. Refresh determines the phase in which to invoke the executable, while the refresh condition determines whether the condition has been met. Set the Refresh attribute to prepareModel when your bindings are dependent on the outcome from the operation. 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. If the incoming request contains no POST data or query parameters, then the lifecycle forwards to the Render Response phase.

    For more information, see Section 10.5.5.1, "Correctly Configuring the Refresh Property of Iterator Bindings". For details about the refresh attribute, see Section A.6.1, "PageDef.xml Syntax".

    In the problem description example, the bindingContainer invokes the ServiceRequestsIterator iterator, which returns the ServiceRequests 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 13-2), and since the UI component is bound to the ProblemDescription binding using an EL expression (#{bindings.problemDescription.inputValue}), that data can be 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 20, "Using Validation and Conversion".

    For 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 value change events are delivered.

    For a detailed explanation of this and the next two phases of the lifecycle, see Chapter 20, "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 16.4, "Using Dynamic Navigation". For a description of action bindings used to invoke business logic, see Section 13.4, "Incorporating Range Navigation into Forms".

  • 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.


    Note:

    Instead of displaying prepareRender as a valid phase for a selection, JDeveloper displays renderModel, which represents the refresh(RENDER_MODEL) method called on the binding container.

    You should set the Refresh attribute of an executable to renderModel when the refreshCondition is dependent on the model. For example, if you want to use the #{adfFacesContext.postback} expression in a RefreshCondition of an executable, you must set the Refresh property to either renderModel or renderModelIfNeeded, which will cause the method to be executed during the prepareRender phase. For more information, see Section 10.5.5.1, "Correctly Configuring the Refresh Property of Iterator Bindings".

  • 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.