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

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

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

13.6 Creating an Input Form

You can create a form that allows a user to enter information for a new record and then commit that record into the data source. While you can choose to use the default ADF Form and then drop the Create operation as a command button, when this type of form is first rendered, it displays the data for the first instance in the collection. The ADF Creation form allows users to create new instances in the collection without first displaying existing instances.

There may be times, however, when you need more control over how a new object is created. For example, you may want certain attributes to be populated programmatically. In this case, you might create a custom method on your application module to handle the creation of objects. To use a custom method to create an input form, instead of using an ADF Creation form, you use a standard form and then drop a custom method as a command button. The custom method will execute when the user clicks the button.


Note:

When you create a row programmatically, you should call the NewRow.setNewRowState(RowSet.STATUS_INITIALIZED method to get the same behavior as the built-in Create action. For more information, see Section 10.4.4, "What You May Need to Know About Create and CreateInsert".

13.6.1 How to Create an Input Form

You create an input form similar to the way you create any other form. However, by selecting an ADF Creation Form when dropping a collection, JDeveloper provides additional functionality automatically.

To create an input form:

  1. From the Data Control Palette, drag the collection for which you wish to create the form, and select ADF Creation Form from the context menu.

  2. In the Edit Form Fields dialog, do not include the Submit button.

  3. From the Data Control Palette, drag the Commit and Rollback operations associated with the root data control, and drop them as command buttons or links.

  4. In the Structure window, select the command button for the commit operation.

  5. In the Property Inspector, 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.

13.6.2 What Happens When You Create an Input Form

When you use an ADF Creation Form to create an input form, JDeveloper:

  • Creates an iterator binding for the collection, an action binding for the Create operation, and attribute bindings for each of the attributes of the object in the collection. It also creates an invoke action in the executables section of the page definition that causes the Create operation to execute during the Render Model phase. If you created command buttons or links using the Commit and Rollback operations, JDeveloper also creates an 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, commandButton components.

For example, to create a simple input form for products in the SRDemo application, you might drop the ProductsList collection from the Data Control Palette as an ADF Creation Form, and then drop the Commit operation as a button below the form, as shown in Figure 13-10.


Note:

This page is an example only and does not exist in the SRDemo application.

Figure 13-10 A Simple Create Product Form

Create product form to enter ID, name, and description

Example 13-13 shows the page definition file for this input form. When the invoke action executes during the prepare render lifecycle phase, the Create operation is invoked, and a new instance for the collection is created. For more information about the lifecycle, see Chapter 13, "What Happens at Runtime: The JSF and ADF Lifecycles"

Example 13-13 Page Definition Code for a Creation Form

<executables>
  <iterator id="ProductListIterator" RangeSize="10" Binds="ProductList"
            DataControl="SRService"/>
  <invokeAction Binds="Create" id="invokeCreate" Refresh="renderModel"
                RefreshCondition="${!adfFacesContext.postback and empty
                                              bindings.exceptionsList}"/>
</executables>
<bindings>
  <action id="Create" RequiresUpdateModel="true" Action="41"
          IterBinding="ProductListIterator"
          InstanceName="SRServiceDataControl.ProductList"
          DataControl="SRServiceDataControl"/>
  <attributeValues id="ProdId" IterBinding="ProductListIterator">
    <AttrNames>
      <Item Value="ProdId"/>
    </AttrNames>
  </attributeValues>
  <attributeValues id="Name" IterBinding="ProductListIterator">
    <AttrNames>
      <Item Value="Name"/>
    </AttrNames>
  </attributeValues>
  <attributeValues id="Description" IterBinding="ProductListIterator">
    <AttrNames>
      <Item Value="Description"/>
    </AttrNames>
  </attributeValues>
  <action id="Commit" InstanceName="SRServiceDataControl"
          DataControl="SRServiceDataControl" RequiresUpdateModel="true"
          Action="100"/>
</bindings>

Anytime the Create operation is invoked (for example, when the page is first rendered), an data object is created. However, since data is cached (which allows the Create operation to do a postback to the server), and since the Create operation is invoked whenever the page enters the renderModel phase, the Create operation will create the same object again when the user revisits the page, perhaps to create another object. Additionally, if errors occur, when the page is rerendered with the error message, the object would again be created.

To prevent duplicates, the invoke action's refreshCondition property is set so that the Create operation will only be invoked whenever there has been no postback to the server and as long as there are no error messages (see Example 13-13 for the EL expression). When the user clicks the Commit button (which is bound to the Commit action through an action binding), the new object with the data is submitted to the data source. If you do want the user to be able to stay on the same page to create multiple objects, see Chapter 13, "What You May Need to Know About Create Forms and the RefreshCondition".

13.6.3 What You May Need to Know About Displaying Sequence Numbers

Because the invokeCreate action is executed before the page is displayed, if you are populating the primary key (in this case the Product ID) using sequences, that number will appear in the input text field. For example, instead of being blank, the Product ID in Figure 13-10 displays the product ID number. This is because the product entity class contains a method that uses an eager fetch to generate a sequence of numbers for the prodId attribute. This populates the value as the row is created.

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.

13.6.4 What You May Need to Know About Create Forms and the RefreshCondition

If the Commit button for the input form does not cause the user to navigate off the page, the page re-renders displaying the data from the last entry. This is because the refreshCondition on the invokeCreate invoke action (${!adfFacesContext.postback and empty bindings.exceptionsList}) causes the action to not be invoked when there is a postback, which is the case when committing the data.

If you want users to be able to stay on the page (for example to create more than one product at a time), you need to change the refreshCondition so that it will allow the invokeCreate action to execute after committing a new object. To do this, you use the setActionListener component within the Commit command component. The setActionListener component allows the command component to set a value before navigating. In this case, the command component will set a flag (named createAnother) on the request scope to true. The refreshCondition can then evaluate this flag to determine whether or not to execute the invokeCreate action, as shown in the following procedure. For more information about the setActionListener component, see Section 17.4.2, "What Happens When You Set Parameters".

To create an input form that can create multiple objects:

  1. Follow the procedure to create an input form.

  2. On the JSF page, drag a setActionListener component from the Component Palette onto the Commit command button.


    Note:

    This procedure assumes that the user will click this Commit button and return to the same page to create another entry. You may wish to change the name of the button to reflect that, for example, Commit and Create Another. You will need to create a different button to navigate off the page.

  3. In the Insert setActionListener dialog, set the following:

    • From: #{true}

    • To: #{requestScope.createAnother}

    This creates a flag named createAnother on the request scope, and sets it to true.

  4. Open the page definition for the JSF page.

  5. Change the refreshCondition for the invokeCreate invoke action from

    ${!adfFacesContext.postback and empty bindings.exceptionsList}
    
    

    to:

    #{empty bindings.expressionList and (!adfFacesContext.postback or
     requestScope.createAnother)}
    
    

    This sets the condition to execute the invokeCreate action when the expression list that contains error messages is empty, and there was not or postback or the createAnother flag on the request scope is set to true.


Note:

The setActionListener component executes during the Invoke Application phase of the lifecycle. Therefore, the refresh attribute for the invokeCreate action must be set to a subsequent phase. In this case, it is set to renderModel by default, and should not be changed.