Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers 10g (10.1.3.1.0) Part Number B25947-01 |
|
|
View PDF |
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 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.
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.
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".
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.
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.
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 ServiceRequest
s 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 ServiceRequests
Iterator
.
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".
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".
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.
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 displayingprepareRender 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.