This chapter describes how to create databound forms in the Fusion web application with data modeled from ADF Business Components, using ADF data controls and ADF Faces components. It describes how to create text fields from individual attributes, generate entire forms from collections for editing and creating new records, and create dynamic forms.
This chapter includes the following sections:
Section 28.2, "Creating Text Fields Using Data Control Attributes"
Section 28.3, "Creating Basic Forms Using Data Control Collections"
Section 28.4, "Creating Command Components Using Data Control Operations"
Section 28.10, "Modifying the UI Components and Bindings on a Form"
You can create UI pages that allow you to display and collect information using data controls created for your business services. For example, using the Data Controls panel, you can drag an attribute for an item, and then choose to display the value either as output text or as an input text field with a label. JDeveloper creates all the necessary JSF tags and binding code needed to display and update the associated data. For more information about the Data Controls panel and the declarative binding experience, see Chapter 17, "Using ADF Model in a Fusion Web Application."
In addition to being able to drop individual attributes, you can drop all attributes for an object at once as a form or table. This chapter includes information on creating forms that display values, forms that allow users to edit values, and forms that collect values (input forms). For information on creating tables, see Chapter 29, "Creating ADF Databound Tables."
Once you drop the UI components, you can then drop built-in operations as command UI components that allow you to navigate through the records in a collection or that allow users to operate on the data, such as committing, deleting, or creating a record. For example, you can create a button that allows users to delete data objects displayed in the form. You can also modify the default components to suit your needs.
You use forms when you need to collect or display a row of data. For example, the Summit sample application for Oracle ADF contains a panel that allows users to update information about their customers as shown in Figure 28-1. This form was created by dragging and dropping the Customers
collection from the Data Controls panel and then selecting the fields to display.
When you create a form, you can also choose to add navigation, so that the user can navigate quickly between records, as shown in Figure 28-2.
You can also add command buttons that invoke processing on the row displayed in the form. For example, you can change values for a record and save those changes in an edit form, or you can create an input form that allows users to create a new record. Figure 28-3 shows an input form where a user can create a new order.
Note:
When the attributes to display in a form are only available at runtime, you can create a dynamic form. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
You may find it helpful to understand other Oracle ADF features before you implement your databound pages. Following are links to other functionality that you may find useful.
ADF view objects: Much of how the components display and function in the form is controlled by the corresponding view objects. For more information, see Chapter 5, "Defining SQL Queries Using View Objects."
ADF application modules: The Data Controls panel, from which you drag databound components to your pages, is populated with representations of view objects that you have added to application modules. For more information, see Chapter 13, "Implementing Business Services with Application Modules."
Adapter-based data controls: If you are using other types of business services, such as EJB components or web services, you can create data controls for those business services as described in Developing Applications with Oracle ADF Data Controls.
ADF Model and data binding: When you create forms in an ADF web application, you use ADF Model and data binding. For more information, see Chapter 17, "Using ADF Model in a Fusion Web Application."
ADF Faces: You also use ADF Faces UI components. For detailed information about developing with ADF Faces, see Developing Web User Interfaces with Oracle ADF Faces.
Advanced UI controls: Basic forms use input and output components. You can also use more advanced components, such as lists, tables, trees, search forms, LOV components, graphs, gauges, treemaps, and more. For more information, see the remaining chapters in Part V, "Creating a Databound Web User Interface".
Task flows: If your form takes part in a transaction, for example an input form, then you may need to use an ADF task flow to invoke certain operations before or after the form is rendered. For more information, see Part IV, "Creating ADF Task Flows".
Page lifecycle: For information about how forms work with the page lifecycle, see Chapter 27, "Understanding the Fusion Page Lifecycle."
Validation: You may want certain fields to be validated before they are submitted to the data store. For more information, see Chapter 11, "Defining Validation and Business Rules Declaratively" and Chapter 18, "Using Validation in the ADF Model Layer."
Active data: If your application uses active data, then you can have the data in your UI components update automatically, whenever the data in the data source changes. For more information, see Chapter 47, "Using the Active Data Service."
JDeveloper allows you to create text fields declaratively in a WYSIWYG development environment for your JSF pages, meaning you can design most aspects of your pages without needing to look at the code. When you drag and drop items from the Data Controls panel, JDeveloper declaratively binds ADF Faces text UI components to attributes on a data control using an attribute binding.
To create an individual text field that can display or update an attribute, you drag and drop an attribute of a collection from the Data Controls panel. For ADF Business Components, the Data Controls panel is populated with elements of your data model that you have defined in one or more application modules.
It may be helpful to have a general understanding of using data control attributes to create text fields. For more information, see Chapter 28, "Creating Text Fields Using Data Control Attributes."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
To create a databound text field:
From the Data Controls panel, select an attribute from a collection. For a description of the icons that represent attributes and other objects in the Data Controls panel, see Section 17.4, "Using the Data Controls Panel."
For example, Figure 28-4 shows the LastName
attribute under the Customers
collection of the BackOfficeAppModuleDataControl
data control in the Summit ADF sample application. This is the attribute to drop to display, update, or insert the customer's last name.
Drag the attribute onto the page, and from the context menu choose the type of UI component to display or collect the attribute value, as shown in Figure 28-5.
For an attribute, you are given the following choices:
Text:
ADF Input Text w/ Label: Creates an ADF Faces inputText
component in which the label
attribute is populated. In addition, a nested validator
component is created, which you can use to add client-side validation.
Tip:
For more information about the various attributes of the inputText
component, see the "Using Input Components and Defining Forms" chapter of Developing Web User Interfaces with Oracle ADF Faces.
ADF Input Text: Creates an ADF Faces inputText
component without a label. In addition, a nested validator
component is generated, which you can use for client-side validation.
ADF Output Text w/ 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.
ADF Output Formatted w/Label: Same as ADF Output Text w/Label, but uses an outputFormatted
component instead of an outputText
component. The outputFormatted
component allows you to add a limited amount of HTML formatting. For more information, see the "Displaying Output Text and Formatted Output Text" section of Developing Web User Interfaces with Oracle ADF Faces.
ADF Output Formatted: Same as ADF Output Formatted w/Label, but without the label.
ADF Label: An ADF Faces outputLabel
component.
List of Values: Creates ADF LOV lists. For more information about how these lists work for Business Components, see Section 5.12, "Working with List of Values (LOV) in View Object Attributes." For more information on how these lists work for adapter-based data controls, see "Creating List of Values Objects" in Developing Applications with Oracle ADF Data Controls. For more information about using the lists on a JSF page, see Section 32.3, "Creating a Selection List."
Single selections: Creates single selection lists. For more information about creating lists on a JSF page, see Section 32.3, "Creating a Selection List."
Note:
These selections are your choices by default. However, the list of components available to use for an attribute can be configured as a control hint on the associated entity or view object. For more information, see Section 4.6, "Defining Attribute Control Hints for Entity Objects" and Section 5.13, "Defining UI Hints for View Objects." For information on adding control hints for adapter-based data controls, see "How to Set UI Hints on Attributes" in Developing Applications with Oracle ADF Data Controls.
For the purposes of this chapter, only the text components (and not the lists) will be discussed.
Among other things, when you drag an attribute onto a JSF page and drop it as a UI component, a page definition file is created for the page (if one does not already exist). For a complete account of what happens when you drag an attribute onto a page, see Section 17.4.2, "What Happens When You Use the Data Controls Panel." Bindings for the iterator and attributes are created and added to the page definition file. Additionally, the necessary JSPX or JSF 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 Controls panel (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 facilitates 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 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. 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.
For example, if you drop the LastName
attribute of the Customers
collection, JDeveloper creates an iterator binding for the Customers
collection.
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. One advantage of this behavior is that the currency of components stays in sync. For example, if the page has a table and and a form dropped from the same collection, the form will show the record of the selected row in the table. If you need the binding to behave differently for the different components, you need to manually create separate iterator bindings.
The iterator binding's rangeSize
attribute determines how many rows of data are fetched from a data control 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 row set. When you create the iterator binding by dragging an attribute or collection on to a page, the attribute is initially set to 25
. For more information about using this attribute, see Section 28.4.2.2, "Iterator RangeSize Attribute Defined." Example 28-1 shows the iterator binding created when you drop an attribute from the Customers
collection.
Example 28-1 Page Definition Code for an Iterator Binding for an Attribute Dropped from a Collection
<executables> <iterator Binds="Customers" RangeSize="25" DataControl="BackOfficeAppModuleDataControl" id="Customers"/> </executables>
For information regarding the iterator binding element attributes, see Appendix B, "Oracle ADF Binding Properties."
This metadata allows the ADF binding container to access the attribute values. Because the iterator binding is an executable, by default, it is invoked when the page is loaded, thereby allowing the iterator to access and iterate over the Customers
collection. This means that the iterator will manage all the Customers
objects in the collection, including determining the current Customers
object or range of Customers
objects.
When you drop an attribute from the Data Controls panel, 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 both to display and to collect attribute values.
For example, if you drop the LastName
attribute under the Customers
collection as an ADF Output Text w/Label widget onto a page, JDeveloper creates an attribute binding for the LastName
attribute. This allows the binding to access the attribute value of the current record. Example 28-2 shows the attribute binding for LastName
created when you drop the attribute from the Customers
collection. Note that the attribute value references the iterator named CustomersIterator
.
Example 28-2 Page Definition Code for an Attribute Binding
<bindings> ... <attributeValues IterBinding="CustomersIterator" id=""LastName <AttrNames> <Item Value="LastName"> </AttrNames> </attributeValues> </bindings>
For information regarding the attribute binding element properties, see Appendix B, "Oracle ADF Binding Properties."
When you create a text field by dropping an attribute from the Data Controls panel, JDeveloper creates the UI component associated with the widget dropped by writing the corresponding tag to the JSF page.
For example, when you drop the LastName
attribute as an Output Text w/Label widget, JDeveloper inserts the tags for a panelLabelAndMessage
component and an outputText
component. It creates an EL expression that binds the label
attribute of the panelLabelAndMessage
component to the label
property of hints created for the LastName
's binding. This expression evaluates to the label hint set on the view object (for more information about hints, see Section 5.13, "Defining UI Hints for View Objects"). It creates another expression that binds the outputText
component's value
attribute to the inputValue
property of the LastName
binding, which evaluates to the value of the LastName
attribute for the current row. An ID is also automatically generated for both components.
Tip:
JDeveloper automatically generates IDs for all ADF Faces components. You can override these values as needed.
Example 28-3 shows the code generated on the JSF page when you drop the LastName
attribute as an Output Text w/Label widget.
Example 28-3 JSF Page Code for an Attribute Dropped as an Output Text w/Label
<af:panelLabelAndMessage label="#{bindings.LastName.hints.label}" id="plam1"> <af:outputText value="#{bindings.LastName.inputValue}" id="ot1"/> </af:panelLabelAndMessage>
If instead you drop the LastName
attribute as an Input Text w/Label widget, JDeveloper creates an inputText
component. As Example 28-4 shows, the value is bound to the inputValue
property of the LastName
binding. Additionally, the following properties are also set:
label
: Bound to the object's label
UI hint.
required
: Bound to the object's mandatory
property.
columns
: Bound to the object's displayWidth
UI hint, which determines how wide the text box will be.
maximumLength
: Bound to the object's precision
property, which determines the maximum number of characters per line that can be entered into the field.
shortDesc
: Bound to the tooltip
UI hint.
In addition, JDeveloper nests a validator
tag within the inputText
component. You can use this tag to create client-side validation rules to supplement any validation rules that exist in the model or business service layers.
For further information regarding the validator
and converter
tags, see the "Validating and Converting Input" chapter of Developing Web User Interfaces with Oracle ADF Faces.
Example 28-4 JSF Page Code for an Attribute Dropped as an Input Text w/Label
<af:inputText value="#{bindings.LastName.inputValue}" label="#{bindings.LastName.hints.label}" required="#{bindings.LastName.hints.mandatory}" columns="#{bindings.LastName.hints.displayWidth}" maximumLength="#{bindings.LastName.hints.precision}"> shortDesc="#{bindings.LastName.hints.tooltip}" id="it1"> <f:validator binding="#{bindings.LastName.validator}"/> </af:inputText>
You can change any of these values to suit your needs. For example, the mandatory
control hint on the view object is set to false
by default, which means that the required
attribute on the component will evaluate to false
as well. You can override this value by setting the required
attribute on the component to true
. If you decide that all instances of the attribute should be mandatory, then you can change the control hint on the view object, and all instances will then be required. For more information about these properties, see Appendix B, "Oracle ADF Binding Properties." For more information on changing these properties at the entity object level, see Section 4.10, "Setting Attribute Properties." For more information on changing these properties at the view object level, see Section 5.2.4, "How to Edit a View Object."
Instead of dropping each of the individual attributes of a collection to create a form, you can drop the collection node to create a form from multiple attributes in the collection.
For example, you could create a page that displays basic information about customers in the Summit ADF sample application by dragging and dropping the Customers
collection.
You can also create forms that provide more functionality than simply displaying data from a collection. For information about creating a form that allows a user to update data, see Section 28.6, "Creating a Form to Edit an Existing Record." For information about creating forms that allow users to create a new object for the collection, see Section 28.8, "Creating an Input Form". You can also create search forms. For more information, see Chapter 33, "Creating ADF Databound Search Forms."
When you create a form using a data control, you bind the UI components to the attributes on the corresponding object in the data control. JDeveloper allows you to do this declaratively by dragging and dropping a collection from the Data Controls panel.
It may be helpful to have an understanding of basic databound forms. For more information, see Section 28.3, "Creating Basic Forms Using Data Control Collections."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
From the Data Controls panel, select the collection that represents the data you wish to display. Figure 28-6 shows the Customers
collection for the BackOfficeAppModuleDataControl
data control.
Drag the collection onto the page, and from the context menu choose ADF Form.
In the Create Form dialog, configure your form.
You can exclude attributes from appearing in the form.
If you do not select the Read-Only Form checkbox, ADF inputText
components are used for most attributes. Each inputText
component has the label
attribute populated. By default, the label obtains its value from a binding to the label
property on the associated binding object.
Attributes that are dates use the InputDate
component.
If a control type control hint has been created for an attribute, or if the attribute has been configured to be a list, then the component set by the hint is used instead.
InputText
components contain a validator
tag that allows you to set up client-side validation for the attribute. If the attribute is a number or a date, a converter
is also included.
Tip:
For more information about the various attributes of the inputText
component, see the "Using Input Components and Defining Forms" chapter of Developing Web User Interfaces with Oracle ADF Faces.
If you select the Read-Only Form checkbox, read-only outputText
components are used. Since the form is meant to display data, no validator
tags are added (though converters are included). Attributes of type Date
use the outputText
component when in a read-only form. All components are placed inside panelLabelAndMessage
components, which have the label
attribute populated, and are placed inside a panelFormLayout
component. This ensures that the labels are aligned appropriately with the outputText
components at runtime.
You can elect to include navigational controls that allow users to navigate through all the data objects in the collection. For more information, see Section 28.5, "Incorporating Range Navigation into Forms."
You can also include a Submit button to submit the HTML form and apply the data in the form to the bindings as part of the JSF/ADF page lifecycle. For additional help in using the dialog, click Help.
If you are building a form that allows users to update data, you now need to drag and drop an operation that will commit the changes to update the record. For more information, see Section 28.6, "Creating a Form to Edit an Existing Record."
Note:
If you select the Fields Generated at Runtime in the Create Form dialog, the attributes to display are determined at runtime based on configuration of the business service. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
Dropping an object as a form from the Data Controls panel has a similar effect as dropping a single attribute, except that multiple attribute bindings and associated UI components are created and all UI components are placed inside a panelFormLayout
component. The attributes on the UI components (such as value
) are bound to properties on that attribute's binding object (such as inputValue
) or to the values of control hints set on the corresponding business object. Example 28-5 shows some of the code generated on the JSF page when you drop the Customers
collection as a default ADF Form.
Note:
If an attribute is marked as hidden on the associated view or entity object, then no corresponding UI is created for it.
Example 28-5 Code on a JSF Page for an Input Form
<af:panelFormLayout id="pfl1"> <af:inputText value="#{bindings.Id.inputValue}" label="#{bindings.Id.hints.label}" required="#{bindings.Id.hints.mandatory}" columns="#{bindings.Id.hints.displayWidth}" maximumLength="#{bindings.Id.hints.precision}" shortDesc="#{bindings.Id.hints.tooltip}" id="it1"> <f:validator binding="#{bindings.Id.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.Id.format}"/> </af:inputText> <af:inputText value="#{bindings.Name.inputValue}" label="#{bindings.Name.hints.label}" required="#{bindings.Name.hints.mandatory}" columns="#{bindings.Name.hints.displayWidth}" maximumLength="#{bindings.Name.hints.precision}" shortDesc="#{bindings.Name.hints.tooltip}" id="it2"> <f:validator binding="#{bindings.Name.validator}"/> </af:inputText> <af:inputText value="#{bindings.Phone.inputValue}" label="#{bindings.Phone.hints.label}" required="#{bindings.Phone.hints.mandatory}" columns="#{bindings.Phone.hints.displayWidth}" maximumLength="#{bindings.Phone.hints.precision}" shortDesc="#{bindings.Phone.hints.tooltip}" id="it3"> <f:validator binding="#{bindings.Phone.validator}"/> </af:inputText> . . . </af:panelFormLayout>
For more information about the code that is generated when you drop an item from the Data Controls panel, see Section 28.2.2, "What Happens When You Create a Text Field."
When you choose to create an input form using an object that contains a defined list of values (LOV), then a selectOneChoice
component is created instead of an inputText
component. For example, the CustomerVO
view object contains defined LOVs for the CountryId
and CreditRatingId
attributes. When you drop the Customers
data control object as an ADF Form, a dropdown list showing all values is created for each LOV (instead of an empty input text field). For more information about how these lists work, see Section 5.12, "Working with List of Values (LOV) in View Object Attributes." For more information on how these lists work for adapter-based data controls, see "Creating List of Values Objects" in Developing Applications with Oracle ADF Data Controls. For more information about using the lists on a JSF page, see Section 32.3, "Creating a Selection List."
Note:
If the object contains a structured attribute (an attribute that is neither a Java primitive type nor a collection), that attribute will not appear in the dialog, and it will not have a corresponding component in the form. You will need to create those fields manually.
In addition to providing a representation of your data objects, the Data Controls panel also has nodes that represent standard operations for use in a form. These built-in operations enable you to declaratively handle common form functions such as navigating between records and committing changes to a database. Most operations are available for individual data collections in a data control. The Commit and Rollback operations are available on the whole data control. When you drag an operation from the Data Controls panel to a page, you are prompted to choose what kind of command component to create, such as a button or a link.
Figure 28-8 shows the operations available for the Countries
collection in the Summit ADF sample application.
This section shows how to create command components from built-in data control operations. For information on other ways you can use command components in a databound page, see Chapter 30, "Using Command Components to Invoke Functionality in the View Layer."
To create a command component based on a data control operation, you drag and drop the operation from the Data Controls panel to a page.
It may be helpful to have a general understanding of using data control operations to create command components. For more information, see Chapter 28, "Creating Command Components Using Data Control Operations."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
To create a command component from an operation:
From the Data Controls panel, drag the operation onto the page.
From the ensuing context menu, choose either ADF Button or ADF Link.
When you drop an operation to create a command component, JDeveloper:
Defines an action binding in the page definition file for the associated operation
Configures the iterator binding to use partial page rendering for the collection
Inserts code in the JSF page for the command component
Action bindings execute business logic. For example, they can invoke operations on the action binding object. These operations operate on the iterator or on the data control itself.
Like value bindings, action bindings for operations contain a reference to the iterator binding when the action binding is bound to one of the iterator-level actions, such as Next
or Previous
. These types of actions are performed by the iterator, which determines the current object and can therefore determine the correct object to display when a navigation button is clicked. Action bindings to actions that are not at the iterator level, such as custom methods on an application module or the commit or rollback operations, will not contain this reference.
Action bindings use the RequiresUpdateModel
property, which determines whether or not the model needs to be updated before the action is executed. In the case of navigation operations, by default this property is set to true
, which means that any changes made at the view layer must be moved to the model before navigation can occur.
Example 28-6 shows the action bindings for the navigation operations.
Example 28-6 Page Definition Code for an Operation Action Binding
<action IterBinding="CustomersIterator" id="First" RequiresUpdateModel="true" Action="first"/> <action IterBinding="CustomersIterator" id="Previous" RequiresUpdateModel="true" Action="previous"/> <action IterBinding="CustomersIterator" id="Next" RequiresUpdateModel="true" Action="next"/> <action IterBinding="CustomersIterator" id="Last" RequiresUpdateModel="true" Action="last"/>
Iterator bindings have a rangeSize
attribute that the binding uses to determine the number of data objects to make available for the page for each iteration. This attribute helps in situations when the number of objects in the data source is quite large. Instead of returning all objects, the iterator binding returns only a set number, which then become accessible to the other bindings. Once the iterator reaches the end of the range, it accesses the next set. Example 28-7 shows the default range size for the Customers
iterator.
Example 28-7 RangeSize Attribute for an Iterator
<iterator Binds="Customers" RangeSize="25"
DataControl="BackOfficeAppModuleDataControl"
id="CustomersIterator"
ChangeEventPolicy="ppr"/>
Note:
This rangeSize
attribute is not the same as the rows
attribute on a table component. For more information, see Table 29-1, "ADF Faces Table Attributes and Populated Values".
When the iterator binding is initially generated, the RangeSize
attribute is set to 25
. This means that a user can view 25 objects, navigating back and forth between them, without needing to access the data source. The iterator keeps track of the current object. Once a user clicks a button that requires a new range (for example, clicking the Next button on object number 25), the binding object executes its associated method against the iterator, and the iterator retrieves another set of 25 records. The bindings then work with that set. You can change this setting as needed. You can set it to -1
to have the full record set returned. If the RangeSize
attribute is not specified, the full record set is returned.
When you create command components using data control operations, JDeveloper creates an EL expression that binds a command button's actionListener
attribute to the execute
property of the action binding for the given operation.
At runtime an action binding will be an instance of the FacesCtrlActionBinding
class, which extends the core JUCtrlActionBinding
implementation class. The FacesCtrlActionBinding
class adds the following methods:
public void execute(ActionEvent event)
: This is the method that is referenced in the actionListener
property, for example #{bindings.First.execute}
.
This expression causes the binding's operation to be invoked on the iterator when a user clicks the button. For example, the First command button's actionListener
attribute is bound to the execute
method on the First
action binding.
public String outcome()
: This can be referenced in an Action
property, for example #{bindings.Next.outcome}
.
This can be used for the result of a method action binding (once converted to a String
) as a JSF navigation outcome to determine the next page to navigate to.
Note:
Using the outcome method on the action binding breaks the separation between the view-controller layer and the model layer, so it should be rarely used.
Every action binding for an operation has an enabled
boolean property that Oracle ADF sets to false
when the operation should not be invoked. By default, JDeveloper binds the UI component's disabled
attribute to this value to determine whether or not the component should be enabled. For example, the UI component for the First button has the following as the value for its disabled
attribute:
#{!bindings.First.enabled}
This expression evaluates to true
whenever the binding is not enabled, that is, when the operation should not be invoked, thereby disabling the button. In this example, because the framework will set the enabled
property on the binding to false
whenever the first record is being shown, the First button will automatically be disabled because its disabled
attribute is set to be true
whenever enabled
is False
. For more information about the enabled
property, see Appendix B, "Oracle ADF Binding Properties."
Example 28-8 shows the code generated after dropping the Create
and Delete
operations as buttons on a page.
Example 28-8 JSF Code For Command Buttons Bound to ADF Operations
<af:button actionListener="#{bindings.Create.execute}" text="Create" disabled="#{!bindings.Create.enabled}" id="b5"/> <af:button actionListener="#{bindings.Delete.execute}" text="Delete" disabled="#{!bindings.Delete.enabled}" id="b6"/>
When the user clicks a command component, the form is submitted and then an action event is fired. Action events might affect only the user interface (for example, a link to change the locale, causing different field prompts to display), or they might involve some logic processing in the back end (for example, a button to navigate to the next record). That event object then takes information about the current data object from the iterator and then passes it to the action binding's method, which is bound to the command component through its actionListener
attribute.
Note:
An action listener is a class that registers to be notified when a command component fires an action event. An action listener contains an action listener method that processes the action event object passed to it by the command component.
For example, when the user clicks a Delete button that was created from the ADF Delete
operation, an action event is fired. This event object stores currency information about the current data object, taken from the iterator. Because the component's actionListener
attribute is bound to the execute
method of the Delete
action binding, the Delete
operation is invoked when the event fires. This method takes the currency information passed in the event object to determine which data object to delete.
Typically, the actionListener
property's value is in the form of an EL expression. For example, if the value of the actionListener
attribute is {bindings.Delete.execute}
, the execute()
method of the Delete
action binding is called.
When you drop an operation or method as a command button, JDeveloper binds the button to the execute method for the operation or method. However, there may be occasions when you need to add logic before or after the existing logic. JDeveloper allows you to add logic to a declarative operation by creating a new method and property on a managed bean that provides access to the binding container. By default, this generated code executes the operation or method. You can then add logic before or after this code. JDeveloper automatically binds the command component to this new method, instead of to the execute property on the original operation or method. Now when the user clicks the button, the new method is executed. For more information, see Section 30.4, "Overriding Declarative Methods."
When you create an ADF Form, if you choose to include navigational controls, JDeveloper includes ADF Faces command components bound to existing navigational logic on the data control. This built-in logic allows the user to navigate through all the data objects in the collection. For example,Figure 28-9 shows a form that would be created if you drag the Countries
collection and drop it as an ADF Form that uses navigation.
Table 28-1 shows the built-in navigation operations provided on data controls and the result of invoking the operation or executing an event bound to the operation. For more information about action events, see Section 28.4.3, "What Happens at Runtime: How Action Events and Action Listeners Work."
Table 28-1 Built-in Navigation Operations
Operation | When invoked, the associated iterator binding will... |
---|---|
First |
Move its current pointer to the beginning of the result set. |
Last |
Move its current pointer to the end of the result set. |
Previous |
Move its current pointer to the preceding object in the result set. If this object is outside the current range, the range is scrolled backward a number of objects equal to the range size. |
Next |
Move its current pointer to the next object in the result set. If this object is outside the current range, the range is scrolled forward a number of objects equal to the range size. |
Previous Set |
Move the range backward a number of objects equal to the range size attribute. |
Next Set |
Move the range forward a number of objects equal to the range size attribute. |
By default, when you choose to include navigation when creating a form using the Data Controls panel, JDeveloper creates First, Last, Previous, and Next buttons that allow the user to navigate within the collection.
You can also add navigation buttons to an existing form manually.
It may be helpful to have an understanding of navigation controls. For more information, see Section 28.5, "Incorporating Range Navigation into Forms."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
To manually add navigation buttons:
From the Data Controls panel, select the operation associated with the collection of objects on which you wish the operation to execute, and drag it onto the JSF page.
For example, if you want to navigate forward through a collection of countries, you would drag the Next operation associated with the Countries
collection. Figure 28-8 shows the operations associated with the Countries
collection.
From the ensuing context menu, choose either ADF Button or ADF Link.
Tip:
You can also drop the First, Previous, Next, and Last buttons at once. To do so, drag the corresponding collection, and from the context menu, choose Navigation > ADF Navigation Buttons.
When you drop a navigation operation from the Data Controls panel, JDeveloper:
Defines an action binding in the page definition file for the associated operations
Configures the iterator binding to use partial page rendering for the collection
Inserts code in the JSF page for the command components
Inserts the partialSubmit
attribute for the component in the JSF page and sets it to true
in order to fire a partial page request when the button is clicked. For more information, see the "Using Partial Triggers" section of Developing Web User Interfaces with Oracle ADF Faces.
For more information on code generated for command components, see Section 28.4.2, "What Happens When You Create Command Components Using Operations."
Example 28-9 shows the code generated on the JSF page for navigation operation buttons.
Example 28-9 JSF Code for Navigation Buttons Bound to ADF Operations
<f:facet name="footer"> <af:panelGroupLayout> <af:button actionListener="#{bindings.First.execute}" text="First" disabled="#{!bindings.First.enabled}" partialSubmit="true" id="cb1"/> <af:button actionListener="#{bindings.Previous.execute}" text="Previous" disabled="#{!bindings.Previous.enabled}" partialSubmit="true" id="cb2"/> <af:button actionListener="#{bindings.Next.execute}" text="Next" disabled="#{!bindings.Next.enabled}" partialSubmit="true" id="cb3"/> <af:button actionListener="#{bindings.Last.execute}" text="Last" disabled="#{!bindings.Last.enabled}" partialSubmit="true" id="cb4"/> </af:panelGroupLayoutr> </f:facet>
When the user clicks a navigation control button, an action event is fired. That event object then takes information about the current data object from the iterator and then passes it to the operation's method, which is bound to the button through its actionListener
attribute.
For more information, see Section 28.4.3, "What Happens at Runtime: How Action Events and Action Listeners Work."
In addition, when a user clicks a navigation button, only those components associated with the same iterator as the button's action binding are processed through the lifecycle. For more information, see Section 27.2.1, "What You May Need to Know About Partial Page Rendering and Iterator Bindings."
You must use the navigation buttons to navigate through the records displayed in a form; you cannot use the browser's back or forward buttons. Because navigation forms automatically use PPR, only part of the page goes through the lifecycle, meaning that when you click a navigation button, the components displaying the data are refreshed and display new data, and you actually remain on the same page. Therefore, when you click the browser's back button, you will be returned to the page that was rendered before the page with the form, instead of to the previous record displayed in the form.
For example, say you are on a page that contains a link to view all current orders. When you click the link, you navigate to a page with a form and the first order, Order #101, is displayed. You then click Next and Order #102 is displayed. You click Next again, and Order #103 is displayed. If you click the browser's back button, you will not be shown Order #102. Instead, you will be returned to the page that contained the link to view all current orders.
When you create a navigable form using the Data Controls panel, the CacheResults
property on the associated iterator is set to true
. This ensures that the iterator's state, including currency information, is cached between requests, allowing it to determine the current object. If this property is set to false
, navigation will not work.
You can create a form that allows a user to edit the current data, and then commit those changes to the data source. To do this, you use operations that can modify data records associated with the collection or the data control itself to create command buttons. For example, you can use the Delete
operation to create a button that allows a user to delete a record from the current range.
For data controls based on ADF Business Components or on EJB session beans that have an explicit commit model, it is important to note that these operations are executed only against objects in the ADF cache. You need to use the Commit
operation on the root data control to actually commit any changes to the data source. You use the data control's Rollback
operation to roll back any changes made to the cached object. If the page is part of a transaction within a bounded task flow, you would most likely use these operations to resolve the transaction in a task flow return activity. For more information, see Section 24.3, "Managing Transactions in Task Flows."
To create an edit form, you drop a collection on your page as a form and then drop the appropriate operations as command components.
It may be helpful to have an understanding of creating edit forms. For more information, see Section 28.6, "Creating a Form to Edit an Existing Record."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
From the Data Controls panel, drag the collection for which you wish to create the form, and choose ADF Form from the context menu.
This creates a form using inputText
components, which will allow the user to edit the data in the fields.
In the Create Form dialog, set the fields and buttons that you would like added to the form and click OK.
Optionally, from the Data Controls panel, select any additional operation associated with the collection that you would like to add to the form, drag it to the page, and choose ADF Button or ADF Link from the context menu.
For example, if you want to be able to delete a country, you would select the Delete
operation associated with the Countries
collection. Figure 28-10 shows the operations associated with the Countries
collection.
Add operations to the page to save or cancel changes.
If the page is not part of a transaction within a bounded task flow, then you need to create buttons that allow the user either to commit or roll back the changes. From the Data Controls panel, drag the Commit and Rollback operations associated with the root-level data control, and drop them as either a command button or a command link. Figure 28-11 shows the commit and rollback operations for the BackOfficeAppModuleDataControl
data control.
If the page is part of a transaction within a bounded task flow, then you can simply enter Commit
and Rollback
as the values for the transaction resolution when creating the task flow return activity. For more information, see Section 24.3, "Managing Transactions in Task Flows."
If you are basing the form on a data control that is based on business services other than ADF Business Components, the Commit
and Rollback
operations might not be available. For more information, see Section 28.6.3, "What You May Need to Know About Working With Data Controls for Stateless Business Services."
Optionally, change the autoSubmit
property of each editable field to true
.
Doing so enables any user changes to be submitted to the page when tabbing out of the field and thus enabling the Commit
and Rollback
operations, if they have not already been enabled by another sequence of events, such as a change to a field plus a button click.
You can access the autoSubmit
property for a field by selecting the field and then scrolling to the Behavior section in the Properties window.
Tip:
If the same page on which you create your edit form also has a table created from the same collection as the form, the table and the form use the same iterator binding, which enables the user to select the record to edit in the form by selecting a row in the table. For more information on creating databound tables, see Section 29.2, "Creating a Basic Table."
For information on what happens when you drop a collection on to a page, see Section 28.3.2, "What Happens When You Create a Form Using a Data Control Collection.".
Dropping any data control operation as a command button causes code generation similar to when you drop navigation operations. For more information, see Section 28.4.2, "What Happens When You Create Command Components Using Operations."
The only difference is that the action bindings for the Commit
and Rollback
operations do not require a reference to the iterator, because they execute a method on the application module (the data control itself), as opposed to the iterator. Note that the Rollback
action has the RequiresUpdateModel
property set to false
. This is because the model should not be updated before the operation is executed, since all changes need to be discarded. Example 28-10 shows the action bindings generated in the page definition file for these operations.
Example 28-10 Action Bindings for Commit and Rollback Operations
<action id="Commit" RequiresUpdateModel="true" Action="commitTransaction" DataControl="BackOfficeAppModuleDataControl"/> <action id="Rollback" RequiresUpdateModel="false" Action="rollbackTransaction" DataControl="BackOfficeAppModuleDataControl"/>
Table 28-2 shows the built-in non-navigation operations provided on data controls and data control objects, along with the result of invoking the operation or executing an event bound to the operation. For more information about action events, see Section 28.4.3, "What Happens at Runtime: How Action Events and Action Listeners Work."
Table 28-2 More Built-in Operations
Operation | When invoked, the associated iterator binding will... |
---|---|
|
Creates a row directly before the current row, inserts the new record into the row set, then moves the current row pointer to the new row. Note that the range does not move, meaning that the last row in the range may now be excluded from the range. For more information about using the Note: |
|
Creates a row directly before the current row, then moves the current row pointer to the new row. Note that the range does not move, meaning that the last row in the range may now be excluded from the range. For data controls based on application modules and most other business services, the record will not be inserted into the row set, preventing a blank row should the user navigate away without actually creating data. The new row will be created when the user submits the data. For more information, see Section 29.4.5, "What You May Need to Know About Create and CreateInsert." However, for JPA-based data controls, the |
|
Same as the Note: |
|
Deletes the current row from the cache and moves the current row pointer to the next row in the result set. Note that the range does not move, meaning that a row may be added to the end of the range. If the last row is deleted, the current row pointer moves to the preceding row. If there are no more rows in the collection, the enabled attribute is set to |
|
Uses the row key as a |
|
Sets the row key as a |
|
Sets the current object on the iterator, given a key's value. For more information, see Section 29.2.3, "What You May Need to Know About Setting the Current Row in a Table." |
|
Refreshes the data collection by first assigning new values to the named bind variables passed as parameters, then (re)executing the view object's query. You would use this operation in the same manner as you would use the This operation appears only for view objects that have defined one or more named bind variables at design time. For more information, see Section 5.10, "Working with Bind Variables.". For EJB and bean data controls, this operation is only available on data control collection objects that are based on parameterized queries. |
|
Causes all items currently in the cache to be committed to the database. |
|
Clears the cache and returns the transaction and iterator to the initial state. Resets the |
|
These operations are used only in search forms. See Chapter 33, "Creating ADF Databound Search Forms" for more information. |
When you create user interfaces based on ADF Business Components services, any data changes that a user makes are not propagated to the underlying database until the user triggers the Commit
operation through a command component.
For user interfaces that are based on data controls for stateless business services, such as stateless EJB session beans or RESTful web services, the Commit
and Rollback
operations are not available. In such cases, you can use custom methods to handle interactions with the underlying database. In the case of EJB data controls, any persistEntity
and mergeEntity
methods in the session bean are exposed through the Data Controls panel, and you can create command components from them. For more information, see "About Commit Models for EJB Session Beans" in Developing Applications with Oracle ADF Data Controls.
In Oracle ADF, there are several ways that you can create a form where the record that is displayed is determined by an input parameter. The following are some of those mechanisms:
Create an ADF Parameter Form based on a data control collection's ExecuteWithParams
operation or on a custom method that takes parameters.
Pass a parameter to the form through a task flow.
Nest a setPropertyListener
tag within a command component and provide application logic within a managed bean to access the parameters and invoke any needed logic.
This section covers the creation of ADF parameter forms based on the ExecuteWithParams
operation. For information on passing parameters to a form through a task flow, see Chapter 22, "Using Parameters in Task Flows" and Section 23.3, "Specifying Parameters for an ADF Region." For information on using the setPropertyListener
tag, see Section 30.3, "Setting Parameter Values Using a Command Component."
The ExecuteWithParams
operation is available only for data control objects that contain parameters, such as those based on view objects containing bind variables and those based on JPA-based beans that contain named queries with parameters. For example, the Summit ADF sample application contains a view object instance called SalesPeople
, which is based on the EmpVO
view object, which contains the bind variable TitleIdBind
. So, as shown in Figure 28-12, the SalesPeople
object contains an ExecuteWithParams
operation with a subnode for the TitleIdBind
parameter.
View object bind variables and JPA parameterized queries allow you to supply attribute values at runtime to the view object or view criteria. The ExecuteWithParams
operation refreshes the data collection by first assigning new values to the named bind variables passed as parameters, then (re)executing the view object's query. For more information about bind variables in view objects, see Section 5.10, "Working with Bind Variables." For more information on named parameters in JPA queries, see "EJB Data Control Prerequisites and Considerations" in Developing Applications with Oracle ADF Data Controls.
To create a form using parameters, you drop the ExecuteWithParams
operation of a collection on to a page as an ADF Parameter Form and then drop the collection itself as an ADF Form.
It may be helpful to have an understanding of creating parameter forms. For more information, see Section 28.7, "Using Parameters to Create a Form."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module."
Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Add bind variables to the view criteria definition as described in Section 5.10.2, "How to Add WHERE Clause Bind Variables to a View Object Definition."
For JPA-based data controls you can create named queries in the session bean or service facade that specify named parameters. For more information, see "EJB Data Control Prerequisites and Considerations" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
To create a parameter form based on the ExecuteWithParams operation:
From the Data Controls panel, drag the ExecuteWithParams
operation for the collection for which you wish to create the form, and choose ADF Parameter Form from the context menu.
In the Create Form dialog, select the parameters on which you want users to be able to query and click OK.
From the Data Controls panel, drag the corresponding collection, and drop it as the type of table or form that you want to display the results of the query based on the user input.
Note:
You can also declaratively incorporate selection lists into parameter forms. To create a selection list, drag a parameter node that is a child of the ExecuteWithParams
operation on to the form. Then drag the ExecuteWithParams
operation and drop it as a button.
When you drop the ExecuteWithParams
operation as a parameter form, JDeveloper:
Inserts code in the JSF page for the form using inputText
components bound to the attribute bindings, and a button
component bound to the ExecuteWithParams
operation.
Defines the following in the page definition file:
A variable iterator for the attributes to use to access the variables (as opposed to a collection's iterator which is used for other forms).
A variableUsage
variable for each parameter to hold the data values. These variables inherit the default value and UI control hints from the view object named bind variables to which they are bound. The variables are local, meaning they live only during a single request. Though they are carried across subsequent post-backs to the same form, they are forgotten (and re-initialized) when a user navigates to some other page.
An action binding for the operation that contains NamedData
elements for each parameter. Each NamedData
element is bound to a corresponding variable. These bindings allow the operation to access the value for the parameter upon execution.
Attribute bindings for the associated attributes.
Example 28-11 shows the executables and bindings in the page definition file that are created by dropping the SalesPeople
collection's ExecuteWithParams
operation on a page.
Example 28-11 Executable and Binding Properties for a Parameter Form
<executables> <variableIterator id="variables"> <variableUsage DataControl="BackOfficeAppModuleDataControl" Binds="SalesPeople.variablesMap.TitleIdBind" Name="ExecuteWithParams_TitleIdBind" IsQueriable="false"/> </variableIterator> <iterator Binds="SalesPeople" RangeSize="25" DataControl="BackOfficeAppModuleDataControl" id="SalesPeopleIterator"/> </executables> <bindings> <action IterBinding="SalesPeopleIterator" id="ExecuteWithParams" RequiresUpdateModel="true" Action="executeWithParams"> <NamedData NDName="TitleIdBind" NDType="java.lang.Integer" NDValue="${bindings.ExecuteWithParams_TitleIdBind}"/> </action> <attributeValues IterBinding="variables" id="TitleIdBind"> <AttrNames> <Item Value="ExecuteWithParams_TitleIdBind"/> </AttrNames> </attributeValues> </bindings>
When you drop the collection that will be used to display the results of the parameter form, code is generated for a basic form, as described in Section 28.3.2, "What Happens When You Create a Form Using a Data Control Collection." In addition, if you use a table to display the results, the partialTriggers
property on table is set to the command button in the parameter form.
When the page is rendered, the framework checks if the page is being rendered for the first time and if the exception list has any items. If both are false, then the framework executes the ExecuteWithParams
action binding. This action binding executes the query, taking the values of the named data elements as values for the needed parameters.
You can create a form that allows a user to enter information for a new record and then commit that record to the data source. Creating a basic input form is similar to creating an edit form, except that the input form also contains the CreateInsert
operation, which causes a blank row to be inserted into the row set which the user can then populate using a form.
You can create a simple input form by dragging and dropping a collection and the appropriate operations from the Data Controls panel on to a page. However, you might need to employ a selection of other techniques to control the user workflow and insert other form processing logic. Such techniques may include:
Using parameters in ADF task flows to pass values with which to pre-populate given attributes of a new record. For more information, see Chapter 22, "Passing Parameters to a View Activity."
Using task flow return activities to set the transaction boundary in the UI, as shown in Section 21.7, "Using Task Flow Return Activities."
Embedding operations in task flow method calls, as shown in Section 22.3, "Passing Parameters to a Bounded Task Flow."
Using managed beans to carry out some operations as shown in Section 30.4, "Overriding Declarative Methods."
Incorporating the form into a region in a task flow as shown in Chapter 23, "Using Task Flows as Regions."
Incorporating the form into a multi-step flow, as shown in Section 24.8, "Using Train Components in Bounded Task Flows."
Placing the form inside a dialog as shown in Section 25.2, "Running a Bounded Task Flow in a Modal Dialog."
Using save points as described inSection 24.3, "Managing Transactions in Task Flows."
The following section shows how to create a basic input form and provides information on a couple of variants.
Creating a basic input form involves creating an edit form and adding a command component for creating new records.
It may be helpful to have an understanding of input forms. For more information, see Section 28.8, "Creating an Input Form."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete this task:
In the Data Controls panel, expand the node for the collection object on which the form is based.
Expand the collection's Operations node and drag the CreateInsert
operation to the edit form.
Note:
The CreateInsert
operation is available only for data controls based on ADF Business Components application modules. If your data control is based on another business service, use the Create
operation instead. For more information on the differences between the two, see Table 28-2.
You can use a task flow to provide the workflow for input forms. Instead of using command components to create new objects, you use a method call activity in the task flow or a method in a managed bean. Instead of using a command component to commit changes, you use a task flow return activity.
For example, you can use a method call activity in a task flow to call a data control object's CreateInsert
operation and then pass control to a view activity that displays a form where the user can enter the data.
To create an input form within a bounded task flow:
Create a bounded task flow as described in Section 20.2, "Creating a Task Flow."
In the Properties window, set the Transaction property to Always Begin New Transaction.
For more information, see Section 24.3, "Managing Transactions in Task Flows."
In the bounded task flow, add a method call activity.
For more information, see Section 21.5, "Using Method Call Activities."
From the Data Controls panel, drag the CreateInsert
operation associated with the collection for which you are creating the form and drop it on the method activity.
With the method call activity still selected, in the Properties window, enter a string for the fixed-outcome
property. After dropping the CreateInsert
operation on to the method call activity, this value is set to CreateInsert
, but you may want to change it to something more specific.
In the overview editor for the task flow, add a view activity that represents the page for the input form. For information on adding view activities, see Section 20.3, "Adding Activities to a Task Flow."
Add a control flow case from the method activity to the view activity.
With the control flow case still selected in the design editor, in the Properties window, make sure that the from-outcome
property of the control flow case is the same as the value of the fixed-outcome
property of the method activity set in Step 5.
Open the page for the view activity in the design editor, and from the Data Controls panel, drag the collection for which the form will be used to create a new record, and choose ADF Form from the context menu.
In the task flow, add a return activity. This return activity must execute the commit
operation on the data control. For these procedures, see Section 21.7, "Using Task Flow Return Activities."
Generally you should use a return activity to call the Commit
operation. However, there might be cases where you need to use a command component for the Commit
operation, such as when the task flow contains data managed by more than one data control or you need to commit the data before the end of the flow.
To create an input form that has a Commit button within the form:
Create an input form as described in Section 28.8.1.1, "Creating an Input Form Using a Bounded Task Flow," but without setting the task flow return activity.
In the Data Controls panel, drag the Commit
operation for the data control that contains the collection associated with the input form, and drop it as a command button.
In the Structure window, select the command button for the commit
operation.
In the Properties window, set the action
to the outcome string that will navigate back to the method activity. You then need to add a control flow case from the page back to the activity, using the same outcome value.
Set the command button's disabled
property to false
.
By default, JDeveloper binds the disabled
attribute of the button to the enabled
property of the binding, causing the button to be disabled when the enabled
property is set to false
. For this binding, the enabled
property is false
until an update has been posted. For the purposes of an input form, the button should always be enabled, since there will be no changes posted before the user needs to create the new object.
If you want the user to be able to create multiple entries before committing to the database, do the following:
To enable an input form to allow multiple entries in a single transaction:
Create an input form as described in Section 28.8.1.1, "Creating an Input Form Using a Bounded Task Flow"
In the task flow, add another control flow case from the view activity back to the method activity, and enter a value for the from-outcome
method. For example, you might enter createAnother
.
Drag and drop a command component from the Components window onto the page, and set the action
attribute to the from-outcome
just created. This will cause the task flow to return to the method activity and reinvoke the CreateInsert
operation.
When you use an ADF Form to create an input form, JDeveloper:
Creates an iterator binding for the collection and an action binding for the CreateInsert
operation in the page definition for the method activity. The CreateInsert
operation is responsible for creating a row in the row set and populating the data source with the entered data. In the page definition for the page, JDeveloper creates an iterator binding for the collection and attribute bindings for each of the attributes of the object in the collection, as for any other form. If you created command buttons or links using the Commit
and Rollback
operations, JDeveloper also creates action bindings for those operations.
Inserts code in the JSF page for the form using ADF Faces inputText
components, and in the case of the operations, button
components.
When the CreateInsert
button is clicked (or a method corresponding to that operation is called), the CreateInsert
action binding is invoked, which executes the CreateInsertRow
action, and a new blank instance for the collection is created.
Note:
When you use a task flow method activity to the call the CreateInsert
operation, the method activity's binding container skips validation for required attributes during routing from the method activity to the view activity, allowing the blank instance to be displayed in the form on the page.
Because the Create
action is executed before the page is displayed, if you are populating the primary key using sequences, the next number in the sequence will appear in the input text field, unlike the rest of the fields, which are blank. The sequence number is displayed because the associated entity class contains a method that uses an eager fetch to generate a sequence of numbers for the primary key attribute. The eager fetch populates the value as the row is created. Therefore, using sequences works as expected with input forms.
However, if instead you've configured the attribute's type to DBSequence
(which uses a database trigger to generate the sequence), the number would not be populated until the object is committed to the database. In this case, the user would see a negative number as a placeholder. To avoid this, you can use the following EL expression for the Rendered
attribute of the input text field:
#{bindings.EmployeeId.inputValue.value > 0}
This expression will display the component only when the value is greater than zero, which will not be the case before it is committed. Similarly, you can simply set the Rendered
attribute to false
. However, then the page will never display the input text field component for the primary key.
If the data control on which your input form is based is a data control for a stateless business service, there is no built-in Commit
operation for you to use to save changes back to the data source.
Instead, you need to use a custom method to save to the database. For more information, see Section 28.6.3, "What You May Need to Know About Working With Data Controls for Stateless Business Services."
Instead of creating static databound forms where you provide tags for each component directly in the page, you can use a dynamic component to create forms where the binding metadata and the components used to display the bound content are determined at runtime.
This section provides information on creating databound dynamic forms. You can also use the dynamic component to create databound tables. For more information, see Section 29.5, "Creating a Table with Dynamic Components."
For more information on the dynamic form component, including how to create a custom data model, see "Determining Components at Runtime" in Developing Web User Interfaces with Oracle ADF Faces.
ADF Faces provides the dynamicComponent
tag that you can use to create model-driven forms and tables where the binding metadata and the tags used to display the bound content are determined at runtime.
The dynamic building of the bindings provides the following possibilities:
Enables you to create pages where the fields displayed and the ADF Faces components used to display them are determined by the data model. Any changes to the data model, such as additional columns or changed UI hints are reflected in the page without having to redesign the page. For more information about UI hints on view objects, see Section 5.13, "Defining UI Hints for View Objects."
Enables you to create pages based on polymorphic view objects, in which the fields available for a given record can differ depending on the record's base entity object. Since the fields to display are determined at runtime, you do not have to include fields in the page that may not apply to certain records or do coding in the view layer to adjust the fields that are displayed for a given record. For more information about building business components that work with multiple row types, see Chapter 7, "Defining Polymorphic View Objects."
You set display information using UI hints on a view object instead of configuring the information in the Create Form or Create Table dialog when you drop the control onto the page. Then if you want to change how the data displays, you need only change it on the view object, and all dynamic components bound to that view object will change their display accordingly.
Figure 28-13 shows a dynamic form at runtime that was designed by setting UI hints for attributes on the CustomerVO
view object and then dropping the Customers
data control collection as a dynamic form. Among the UI hints set were LABEL
and DISPLAYHINT
(the latter of which can be set to Hide
in order to not include the given attribute in the dynamic form).
The following ADF Faces components can be rendered at runtime when you use af:dynamicComponent
at design time:
af:inputText
af:inputDate
af:inputListOfValues
af:selectOneChoice
af:selectManyChoice
af:selectOneListbox
af:selectManyListbox
af:selectOneRadio
af:selectBooleanRadio
af:selectBooleanCheckbox
af:selectManyCheckbox
To create a dynamic form, you drop a collection from the data controls panel as an ADF Form and specify that the fields be generated dynamically.
It may be helpful to have an understanding of dynamic forms. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
If you want to take advantage of dynamic forms to display records that contain varying attributes, you first need to have data objects that contain that capability. For information on creating view objects with this capability, see Section 7, "Defining Polymorphic View Objects."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
Set UI hints on the view object or data control structure definition file that corresponds to the collection for which you are creating the dynamic form.
UI hints determine things such as the type of UI component to use to display the attribute, the label, the tooltip, whether the field should be automatically submitted, etc. You can also determine whether a given attribute is displayed or hidden. For procedures on creating UI hints, see Section 5.13, "Defining UI Hints for View Objects."
Optionally, for the Category
hint on each view object attribute, specify a category or click the New Category icon to create a new category.
Any attributes that have the same category can be grouped together in dynamic forms that you create based on that view object.
Optionally, for any categories that you have created in step 2, set the UI hints for the category's label and tooltip. These can be set in the UI Categories tab of the view object's overview editor.
From the Data Controls panel, select the collection that represents the view object.
Drag the collection onto the page, and from the context menu, choose ADF Form.
In the Create Form dialog, select the Fields Generated at Runtime checkbox.
If you have specified any categories for attributes in step 2, select the Include Field Groups checkbox in order for the form to group the attributes according to those categories.
When you drop a collection as a dynamic form on a page, the following things happen:
The page definition is populated with a variableIterator
binding, an iterator
binding to the iterator, and a tree
value binding.
The JSF page is populated with one or more iterator
and dynamicComponent
tags. In addition, if the Include Field Groups option is selected, switcher
and group
tags are added.
The page definition file for a dynamic form contains the following executables and bindings:
variableIterator: an internal iterator that contains variables declared for the binding container.
iterator: the iterator binding for the collection. For more information on iterator bindings, see Section 28.2.2.1, "Iterator Bindings Created in the Page Definition File."
tree: the value binding for the attributes of the collection. Unlike a standard form, which has individual value bindings for each attribute set at design time, a dynamic form uses a single tree value binding to encompass the attributes that are exposed at runtime.
Tree value bindings are also used for databound tables (both standard and dynamic). For more information, see Section 29.2.2.1, "Iterator and Value Bindings for Tables."
Example 28-12 shows the bindings for a page that contains a dynamic form component based on the Customers
collection.
Example 28-12 Page Definition Code for a Dynamic Component
<executables> <variableIterator id="variables"/> <iterator Binds="SummitAppModuleDataControl.dataProvider.BackOfficeAM.Customers" DataControl="SummitAppModuleDataControl" RangeSize="25" id="CustomersIterator"/> </executables> <bindings> <tree IterBinding="CustomersIterator" id="Customers"> <nodeDefinition DefName="oracle.summit.model.views.CustomerVO" Name="Customers0"/> </tree> </bindings>
In the JSF page, JDeveloper inserts an iterator
tag, within which it nests a dynamicComponent
tag. The iterator
tag loops through all of the attributes that are exposed by the collection at runtime and uses the dynamicComponent
tag to render the appropriate component for each attribute on the page.
Example 28-13 shows the code that is generated when you drop the Customers
data control object as a dynamic form (but do not select the Include Field Groups option).
Example 28-13 JSF Page Code for a Dynamic Form
<af:panelFormLayout id="pfl1"> <af:iterator id="i1" value="#{bindings.Customers.attributesModel.attributes}" var="attr"> <af:dynamicComponent id="d2" attributeModel="#{attr}"/> value="#{bindings[attr.containerName][attr.name].inputValue}"/> </af:iterator> </af:panelFormLayout>
The value
attribute of the iterator
tag uses an EL expression that evaluates to the attributesModel.attributes
property of the collection's tree binding. The attributesModel
property is used to retrieve the data object's attributes and their metadata, such as component type, label, tooltip, and other properties of the real component to be rendered. The attributes
property of attributesModel
signifies that a flat (unhierarchical) list of displayable attributes and their metadata is provided.
The attributeModel
attribute of the dynamicComponent
tag is bound to the EL expression #{attr}
, which references the variable that is defined in the iterator's var
attribute and that serves as a pointer to the current attribute of the data control collection and its corresponding metadata. The EL expression for the dynamicComponent
's value
attribute also references the variable attr
.
If you have selected the Include Field Groups checkbox in the Create Form dialog, the generated JSF page includes the switcher
and group
tags, in addition to the tags described in Section 28.9.3.2, "Tags Created for a Dynamic Form without Grouping."
The switcher
tag is nested directly within a an iterator
tag. Within the switcher
tag are nested facet
tags named GROUP
and ATTRIBUTE
. The GROUP
facet contains a group
tag, within which is an outputText
tag to display the group name and an iterator
tag, which contains a dynamicComponent
tag. The ATTRIBUTE
facet only contains a dynamicComponent
tag.
For each attribute that the high-level iterator
iterates over, the switcher dynamically determines whether to render a group or a component for the individual attribute. If it renders a group, the iterator within the group then is used to render the components for the attributes within that group.
Example 28-14 shows the code that is generated if you create a dynamic form based on the Customers
collection and choose to include field groups.
Example 28-14 JSF Page Code for a Dynamic Form With Attribute Groups
<af:panelFormLayout id="pfl1"> <af:iterator id="i1" value="#{bindings.Customers.attributesModel.hierarchicalAttributes}" var="attr"> <af:switcher id="sw1" facetName="#{attr.descriptorType}" defaultFacet="ATTRIBUTE"> <f:facet name="GROUP"> <af:group title="#{attr.label}" id="g1"> <af:outputText value="#{attr.name}" id="ot1"/> <af:iterator id="gi1" value="#{attr.descriptors}" var="nestedAttr"> <af:dynamicComponent id="gd1" attributeModel="#{nestedAttr}"/> </af:iterator> </af:group> </f:facet> <f:facet name="ATTRIBUTE"> <af:dynamicComponent id="ad1" attributeModel="#{attr}"/> </f:facet> </af:switcher> </af:iterator> </af:panelFormLayout>
The value
attribute of the iterator
tag uses an EL expression that evaluates to the attributesModel.hierarchicalAttributes
property of the collection's tree binding. The attributesModel
property is used to retrieve the data object's attributes and their metadata, such as component type, label, tooltip, and other properties of the real component to be rendered. The hierarchicalAttributes
property signifies that a hierarchical list of displayable attributes and their metadata is provided, including any categories that have been set for any attributes in the UI hints.
The attributeModel
attribute of the dynamicComponent
tag is set to the EL expression #{attr}, which references the variable that is defined in the iterator's var
attribute and that serves as a pointer to the current attribute (or category) of the data control collection and its corresponding metadata.
When a page with dynamic components is rendered, the bindings are created just as they are when items are dropped from the Data Controls panel at design time, except that they are created at runtime.
At runtime, the iterator
iterates over the set of attributes and instantiates a dynamicComponent
for each attribute. The dynamic component uses its attributeModel
property to obtain information from the iterator about the current attribute, such as label and control type. Each dynamicComponent
then renders a component based on the metadata that is returned for the attribute.
If the DISPLAYHINT
UI hint for an attribute is set to Hide
, no component for the attribute is rendered.
If the dynamic form is created from a data control object that is based on a polymorphic view object, the rendered components depend on the row type for the currently selected record.
By default, standard ADF Faces converters and validators are applied to the components generated at runtime when using dynamic components. For example, converterDateTime
converters are applied to components based on attributes of type TimeStamp
.
If you need to add more specific validation or conversion to a component, you can do so by adding ADF Faces validator and converter tags to the source for the dynamic component and use the tags' disabled
attribute to determine on which attributes the validators and converters are applied.
It may be helpful to have an understanding of dynamic forms. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete this task:
To manually insert an ADF Faces validator or converter into a dynamic form:
Open the page containing the dynamic component in the source editor.
Within the <af:dynamicComponent>
tag, insert any validator and converter components that you want to use.
Within the each validator and converter tag, insert the disabled
attribute and bind it to an EL expression that disables the tag for all attributes except for those to which you want to apply it.
For example, the following expression would enable a validator only for the Hiredate
attribute:
#{attr.name == 'Hiredate' ? false : true}
Example 28-15 shows a dynamic component with two validators and two converters applied.
Example 28-15 Validators and Converters Applied to a Dynamic Component
<af:panelFormLayout id="pfl1"> <af:iterator id="i1" value="#{bindings.EmpVO1.attributesModel.attributes}" var="attr"> <af:dynamicComponent value="#{bindings[attr.containerName][attr.name].inputValue}" attributeModel="#{attr}" id="dc1"/> <af:convertDateTime disabled="#{attr.name == 'Hiredate' ? false : true}" pattern="yyyy/MM/dd"/> <af:convertNumber disabled="#{attr.name == 'Sal' ? false : true}" pattern="#,###,###" /> <af:validateLength disabled="#{attr.name == 'Job' ? false : true}" maximum="10" hintMaximum="maxmum length is 10"/> <af:validateLongRange disabled="#{attr.name == 'Sal' ? false : true}" minimum="1000"/> </af:dynamicComponent> </af:iterator> </af:panelFormLayout>
When you create a dynamic form, you essentially create a block of components that are rendered dynamically. It is possible place static components before and after that block of components, but you can not intersperse static components within that block.
Example 28-16 illustrates the granularity of mixing static and dynamic components that is possible. It consists of three group
tags, the first and third of which contain static content and the second of which contains an iterator
tag with a nested dynamicComponent
tag.
Example 28-16 Mixing Static Content with Dynamic Content
<af:group title="static before dynamic" id="g1"> <af:separator id="sp2"/> <af:inputText value="#{bindings.Empno.inputValue}" label="Static Empno" required="#{bindings.Empno.hints.mandatory}" columns="#{bindings.Empno.hints.displayWidth}" maximumLength="#{bindings.Empno.hints.precision}" shortDesc="#{bindings.Empno.hints.tooltip}" id="it1"> <f:validator binding="#{bindings.Empno.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.Empno.format}"/> </af:inputText> </af:group> <af:group title="dynamic part" id="g2"> <af:separator id="sp3"/> <af:panelFormLayout id="pfl1"> <af:iterator id="i1" value="#{bindings.EmpVO1.attributesModel.attributes}" var="attr"> <af:dynamicComponent value="#{bindings[attr.containerName][attr.name].inputValue}" id="dc1" attributeModel="#{attr}"/> </af:iterator> </af:panelFormLayout> </af:group> <af:group title="static after dynamic" id="g3"> <af:separator id="sp4"/> <af:inputText value="#{bindings.Ename.inputValue}" label="Static Ename" required="#{bindings.Ename.hints.mandatory}" columns="#{bindings.Ename.hints.displayWidth}" maximumLength="#{bindings.Ename.hints.precision}" shortDesc="#{bindings.Ename.hints.tooltip}" id="it2"> <f:validator binding="#{bindings.Ename.validator}"/> </af:inputText> </af:group> <af:button text="Back" id="cbb1" action="back"/>
If you have any custom processing that you need to do to determine how the dynamic component is rendered, you can do so in a managed bean and then bind the dynamic component's attributeModel
property to the appropriate bean method.
It may be helpful to have an understanding of dynamic forms. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete this task:
To programmatically set a dynamic component's behavior:
In the UI project that contains the dynamic component, create a Java class that extends the oracle.adf.view.rich.model.BaseAttributeDescriptor
class.
Example 28-17 shows a sample class that adds a method to apply a custom style to the label for the Sal
attribute.
Example 28-17 Custom Implementation of BaseAttributeDescriptor
public class CustomizedDescriptor extends BaseAttributeDescriptor { public CustomizedDescriptor(BaseAttributeDescriptor base) { _base = base; } public Object getLabelStyle() { if (getName().equals("Sal")) return "color:red; font-weight:bold"; else return null; }
Create a managed bean for the page. For more information, see Section 26.4, "Using a Managed Bean in a Fusion Web Application."
In the managed bean, create a method that returns an instance of the custom descriptor that you created in step 1. Example 28-18 shows such a method.
Example 28-18 Managed Bean Method That Returns a Custom Attribute Descriptor
public CustomizedDescriptor getCustomizedAttributes(String attrName) { // create value expression for "#{attrName}" and evaluate it to get object // of "attr" BaseAttributeDescriptor attrMetadata = null; Class klass = null; try { klass = ClassLoaderUtils.loadClass("oracle.adf.view.rich.model.BaseAttributeDescriptor"); } catch (ClassNotFoundException e) { throw new RuntimeException("Can not find class oracle.adf.view.rich.model.BaseAttributeDescriptor"); } FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ValueExpression valueExpression = createValueExpression(attrName, klass); if (valueExpression != null) attrMetadata = (BaseAttributeDescriptor)valueExpression.getValue(elContext); return new CustomizedDescriptor(attrMetadata); }
In the source editor for the page containing the dynamic component, bind the dynamic component's attributeModel
property to the managed bean method that returns the customized attribute descriptor.
Example 28-19 shows a dynamicComponent
tag where its attributeModel
attribute has been set to an EL expression that references the getCustomizedAttributes
method of the attributeCustomBean
managed bean.
Example 28-19 attributeModel Attribute Bound to a Managed Bean
<af:panelFormLayout id="pfl1">
<af:iterator id="i1" value="#{bindings.EmpVO1.attributesModel.attributes}"
var="attr">
<af:dynamicComponent value="#{bindings[attr.containerName][attr.name].inputValue}" attributeModel="#{attributeCustomBean.getCustomizedAttributes('attr')}" />
</af:iterator>
</af:panelFormLayout>
If you need to access a dynamic component instance programmatically to make changes based on a user action, you can do so by using a managed bean.
It may be helpful to have an understanding of dynamic forms. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete this task:
To programmatically access a dynamic component's binding instance:
Create a managed bean method that identifies dynamic component, casts the component to RichDynamicComponent
, and then applies any changes.
For more information, see Section 26.4, "Using a Managed Bean in a Fusion Web Application."
In the page containing the dynamic component, add a command component to the page and bind its actionListener
property to the managed bean method.
Example 28-20 shows a managed bean method that changes the label style for a dynamic component.
Example 28-20 Managed Bean Code to Access a Dynamic Component's Binding Instance
public void changeLabelColor (ActionEvent event) { UIComponent component = event.getComponent().getParent(); component = component.findComponent("pfl1"); while(component != null) { if(component.getId().equals("it1")) { RichDynamicComponent rdc = (RichDynamicComponent)component; rdc.setLabelStyle("color:red"); break; } else component = component.getChildren().get(0); } }
If you need to access a runtime binding instance of a dynamic component programmatically, you can do so using a managed bean.
It may be helpful to have an understanding of dynamic forms. For more information, see Section 28.9, "Creating a Form with Dynamic Components."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete this task:
To access a dynamic component's binding instance programmatically:
Create a managed bean method that accesses the binding container through the FacesContext
, gets the AttributesModel
, and then applies the desired business logic.
For more information, see Section 26.4, "Using a Managed Bean in a Fusion Web Application."
In the page containing the dynamic component, add a command component to the page and bind its actionListener
property to the managed bean method.
Example 28-21 illustrates a managed bean method that will set the DeptNo
value of the current row to 9999.
Example 28-21 Managed Bean Method That Accesses a Dynamic Component's Binding Context
public void setValueThroughBinding(ActionEvent event) { // get binding container FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ValueExpression valueExpression = createValueExpression("bindings", DCBindingContainer.class); DCBindingContainer binding = (DCBindingContainer) valueExpression.getValue(elContext); // get AttributesModel and attribute metadata list valueExpression = createValueExpression("bindings.EmpVO1.attributesModel", AttributesModel.class); AttributesModel attributesModel = (AttributesModel) valueExpression.getValue(elContext); List<BaseAttributeDescriptor> attrList = attributesModel.getAttributes(); // get AttributeMetadata for "Empno" BaseAttributeDescriptor deptNoAttributeBase = null; FacesAttributeDescriptor deptNoAttribute = null; for (BaseAttributeDescriptor attrDescriptor: attrList) { if ("Comm".equals(attrDescriptor.getName())) { deptNoAttributeBase = attrDescriptor; break; } } deptNoAttribute = (FacesAttributeDescriptor)deptNoAttributeBase; if (deptNoAttribute == null || deptNoAttribute.getContainerName() == null) { System.out.println("AttributesModel of Empno or its model name"); System.out.println("can not be found."); return; } // get Deptno attribute value binding, set input value JUFormBinding fb = (JUFormBinding) binding.findExecutableBinding((String) deptNoAttribute.getContainerName()); JUCtrlValueBinding valueBinding = (JUCtrlValueBinding) fb.getControlBinding(deptNoAttribute.getName()); valueBinding.setInputValue(Integer.valueOf(9999)); System.out.println("Found JUCtrlValueBinding " + deptNoAttribute.getName()"); System.out.println("set its value to 9999."); }
Once you use the Data Controls panel to create any type of form (except a dynamic form), you can then delete attributes, change the order in which they are displayed, change the component used to display data, and change the attribute to which the components are bound.
Note:
You cannot change how a dynamic form displays using the following procedures. You must change display information on the view object or entity object instead.
You can modify certain aspects of the default components dropped from the Data Controls panel. You can use the Structure window to change the order in which components are displayed, to add new components or change existing components, or to delete components. You can use the Properties window to change or delete bindings, or to change the label displayed for a component.
It may be helpful to have a general understanding of working with UI components after they have been generated. For more information, see Section 28.10, "Modifying the UI Components and Bindings on a Form."
You may also find it helpful to understand other ADF functionality and features. For more information, see Section 28.1.2, "Additional Functionality for Databound Pages."
You will need to complete these tasks:
Create an application module that contains instances of the view objects that you want in your data model, as described in Section 13.2, "Creating and Modifying an Application Module." Alternatively, if you are using another type of business service, create a data control for that business service as described in "Exposing Business Services with Data Controls" in Developing Applications with Oracle ADF Data Controls.
Create a JSF page as described in Section 26.3, "Creating a Web Page."
To modify default components and bindings:
Use the Structure window to do the following:
Change the order of the UI components by dragging them up or down the tree. A black line with an arrowhead denotes where the UI component will be placed.
Add a UI component. Right-click an existing UI component in the Structure window and choose to place the new component before, after, or inside the selected component. You then choose from a list of UI components.
Bind a UI component. Right-click an existing UI component in the Structure window and choose Bind to ADF Control. You can then select the object to which you want your component bound.
Rebind a UI component. Right-click an existing UI component in the Structure window and choose Rebind to another ADF Control. You can then select the new control object to which you want your component bound.
Delete a UI component. Right-click the component and choose Delete. If you wish to keep the component, but delete the binding, you need to use the Properties window. See the second bullet point in Step 2.
With the UI component selected in the Structure window, you can then do the following in the Properties window:
Add a non-ADF binding for the UI component. Enter an EL expression in the Value field, or use the dropdown menu and choose Edit.
Delete a binding for the UI component by deleting the EL expression.
Change the label for the UI component. By default, the label is bound to the binding's label
property of its hint. This property allows your page to use the UI control hints for labels that you have defined for your entity object attributes or view object attributes. The UI hints allow you to change the value once and have it appear the same on all pages that display the label.
You can change the label just for the current page. To do so, select the label
attribute. You can enter text or an EL expression to bind the label value to something else, for example, a key in a properties or resource file.
For example, the inputText
component used to display the name of a product might have the following for its Label
attribute:
#{bindings.ProductName.hints.label}
However, you could change the expression to instead bind to a key in a properties file, for example:
#{properties['productName']}
In this example, properties
is a variable defined in the JSF page used to load a properties file.
When you modify how an attribute is displayed by moving or changing the UI component, JDeveloper changes the corresponding code on the JSF page. When you use the binding editors to add or change a binding, JDeveloper adds the code to the JSF page, and also adds the appropriate elements to the page definition file.