Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3) B25386-01 |
|
![]() Previous |
![]() Next |
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.
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:
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.
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".
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".
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.
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".
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 findAllServiceRequest
Iter
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".
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.
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.
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.
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.