Browsing and Editing Data
By Steve Muench
Drag and drop your way to the Web.
In past columns, I have shown the various components Oracle ADF provides to simplify the process of building database-centric business services. The application module provides the transactional component clients use to browse and modify view object data, the view object performs SQL queries and coordinates with entity objects to handle updates, and the entity object encapsulates business domain data and validation for rows in a table.
This column builds on our understanding of these Oracle ADF data access components by constructing a simple Web application with browse and edit functionality, using the data exposed by an application module. (Note that the steps in this article use Oracle JDeveloper 10g, Release 10.1.2, which is available on OTN.)
Browsing Data Page by Page
To build the application, you start with data from the SCOTT.EMP sample table and an Oracle JDeveloper 10g connection to the sample database. You then generate an entity object for the EMP table, a corresponding updatable view object, and an application module for clients to work with. Then you proceed to put that data on a Web page.
With Oracle JDeveloper 10g running and a connection defined for the SCOTT account, create a new application workspace. Choose File -> New , and select Application Workspace from the General category in the New Gallery dialog box. In the Create Application Workspace dialog box, enter a name for the application, select the Web Application [Default] application template, and click on OK .
Next, right-click on your newly created Model project from the Applications Navigator and select New from the context menu. In the New Gallery dialog box, pick the (Business Tier) Business Components category and double-click on Business Components from Tables . In the Business Components Project Initialization dialog box, select the SCOTT database connection and click on OK . After the welcome page, you go through a series of four wizard pages to create the business components. On the first page, select an Emp entity object for the EMP table. On the second page, select an updatable EmpView view object for the Emp entity object. On the third page, click on Next to skip creating any read-only view objects. On the fourth page, name the application module HRModule . Finally, click on Finish to generate the objects.
With the simple back-end application components created, the focus shifts to the front end. Start by creating a BrowseEmps Web page showing data from the EmpView view object in an HTML table. In the Applications Navigator, right-click on the ViewController project and select Open Struts Page Flow Diagram from the context menu. The page flow diagram that appears shows all the pages in our Web tier as well as the navigation flows between those pages. Because the diagram starts out empty, you need to drop a new page onto it to get started.
From the Component palette, drag a Data Page component and drop it onto the page flow diagram. Change the page name under the icon that appears to /BrowseEmps . It's important that the page name begin with a slash; otherwise, you'll get an "invalid path" error message when you try to run the page.
To edit the contents of the page, double-click on it to open the visual designer. The first time you do this, the Create Page dialog box appears. Pick /BrowseEmps.uix from the Page Name drop-down list, and click on OK . The visual page designer appears.
Click on the Data Controls tab below the palettes to flip to the Data Control palette, and expand the HRModuleDataControl node to see the EmpView1 datasource. The data control is the abstraction for any business service, whether implemented by an application module, a Web service, a custom Java class, or other means. The Data Control palette shows the datasources and operations each service supports.
To put EmpView data on the BrowseEmps page, drag the EmpView1 datasource from the Data Control palette window and drop it onto the page. You can immediately run the application to see the results, by clicking back on the page flow diagram, right-clicking on the /BrowseEmps page icon, and selecting Run from the context menu. Oracle JDeveloper 10g starts the embedded Oracle Application Server Containers for J2EE (OC4J) server and launches your default Web browser. When the page appears, you'll see the employee data in a table display that lets users navigate page by page through the data, sort by any column by clicking on the column header, and select a desired row.
Improving the Web User Experience
When you test the browse page, you'll notice that the first page shows rows 1 through 10 as expected but that the second page shows rows 5 through 14 instead of rows 11 through 14. This occurs because the default behavior of a view object is to keep the last page of results full. It's easy to turn off this behavior to make page-by-page scrolling work the way a Web user would expect.
Back in your Model project, double-click on the EmpView view object and select the Tuning panel in the View Object Editor window. Simply uncheck the "Fill Last Page of Rows when Paging through Rowset" property to disable this default paging behavior, and click on OK to save the change.
Next, configure two configuration properties of the application module to conform with best practices in Web applications. In the Applications Navigator, right-click on the HRModule component and choose Configurations from the context menu. Click on Edit to modify the HRModuleLocal set of configuration properties, and select the Properties tab in the new window. Scroll down to the jbo.locking.mode property in the alphabetical list, and change the value from pessimistic to optimistic , to prevent a Web session from holding locks while the user clicks away to do other things. Next, select the Pooling and Scalability tab. Because you are not running in a multiserver configuration where application failover makes sense, you can improve performance by unchecking the "Failover Transaction State Upon Managed Release" property. Click on OK twice to close the configuration editor.
Next, change BrowseEmps to show 5 rows per page instead of 10, the default. Return from the page flow back to the visual designer window for the BrowseEmps page. Note that the top of the Structure window lets you select from three minitabs that show page-related structural information. If you position your cursor over the three minitabs, you'll see that they are named XML Structure, Design Structure, and UI Model. Select the UI Model tab to see the data bound to the current page. Click on the EmpView1Iterator icon, and look at the Property Inspector. Note that EmpView1Iterator has a property called Range Size, with a value of 10. An iterator keeps track of the current row in a particular datasource and lets users scroll up and down through its rows. The range size of an iterator controls how many rows are displayed on each page during scrolling. Change this property value in the Property Inspector from 10 to 5.
Now, close your browser to clear the session-duration cookie that was set by the failover feature during the earlier run, and rerun the BrowseEmps page from the page flow diagram as before. This time you'll see five rows per page, with the last page showing only rows 11 through 14, as expected.
Creating an Input Form
Now repeat the steps you followed above, to create a second page that enables users to edit employee information. Back in the page flow diagram, drag and drop another Data Page component from the Component palette and name it /EditEmp . Double-click on the new page, and select /EditEmp.uix from the Create Page dialog box. In the visual designer for the EditEmp page, go to the Data Control palette and note the "Drag and Drop As:" drop-down list at the bottom. Change the setting from Read-Only Table , the default, to Input Form (With Navigation) . Then drag the EmpView1 datasource and drop it onto the page.
Remove the Submit button, by selecting it in the visual editor and pressing the Delete key. Recall from earlier that, besides datasources, the Data Control palette also shows operations supported by each business service. Expand the Operations folder that is a direct child of HRModuleDataControl , drag the Commit operation to the form, and drop it just to the right of the existing Last button. By default, the Commit button will be disabled until the user has made some edits, but making it always-enabled is easy. With the Commit button selected in the visual editor, find the disabled property in the Property Inspector and set its value to false. (You may need to first set the value to true and then to false.) Next, change the value of the Commit button's event property from the generic name action to Commit , to match the name of the built-in Commit operation. Finally, go to the Structure window, select the Design Structure minitab, and select the form component (an immediate child of body ). In the Property Inspector, change the form's method property from GET to POST . After saving your changes, you can now run the new EditEmp page from the page flow diagram to try out its functionality. For example, try navigating in the page and committing a modified Sal value .
Connecting the Pages
You've now tested our two pages independently, but they would be more useful to the end user if you connected them to allow browsing, selecting, and editing to all be in one smooth set of steps. Because you did most of the preceding tasks with a drag, a drop, and a few property changes, you might expect that connecting the BrowseEmps and EditEmp pages would be just as simple. And you'd be right!
Back in the page flow diagram, you can enable the BrowseEmps page to forward control to the EditEmp page. In the Component palette, select the Forward component, and connect the BrowseEmps page to the EditEmp page by clicking first on BrowseEmps and then on EditEmp . An arrow representing the forward appears, connecting the page icons. Because you'll also want the EditEmp page to forward control back to the browse page when users commit their edits, repeat the process to connect EditEmp back to BrowseEmps with another Forward component. This time, after clicking on EditEmp , note that you can control the route of your line by clicking on the diagram surface various times to indicate your line "route," before finally clicking on the BrowseEmps icon to end the operation. You can always add extra points in a line in the diagram after the fact, by shift-clicking at the spots in the middle of a line where you want to add the points. Shift-clicking on an existing midpoint removes it later if you don't like it. By default, the diagram will try to automatically straighten your lines, but if you want your lines to stay exactly as you created them, right-click on the diagram surface and pick Display Properties from the context menu to turn off that preference.
Back in the visual designer for the BrowseEmps page, it's time to add an Edit button to navigate to the EditEmp page. Drag a submitButton from the Component palette and drop it into the space between the existing Select and words and the page navigation control in the table header area, just above the Ename column. In the Property Inspector, change its text property to Edit and its event property to Edit .
At this point, you have an Edit button on the BrowseEmps page that triggers an event named Edit and a Commit button on the EditEmp page that triggers a Commit event. The last step is to rename the forward lines between our pages so that their names match the names of the event that will trigger each navigation. So, back in the page flow diagram, double-click on the default success label on the forward from BrowseEmps to EditEmp , and change the name to Edit to match the Edit button's Edit event. Repeat these steps to rename the forward from EditEmp to BrowseEmps from success to Commit , to match the Commit button's Commit event. With this last touch, the browse and edit pages are done, so you can now run the BrowseEmps page from the page flow diagram and play proudly with the little application you've assembled so quickly.
As an extra-credit exercise, you can try adding some declarative validation rules to the Emp entity object in your Model project. For example, try adding a range validation on the Sal attribute, and rerun the application. On the edit page, try entering an invalid salary value, and you'll see even more of the default functionality Oracle ADF provides when errors are consistently reported in the information area at the top of the page.
Hopefully, this whirlwind tour of constructing a simple ADF Web application has helped you understand the visual and declarative features Oracle JDeveloper 10g and Oracle ADF offer for rapidly building database-centric Web applications. A future column will explore the Oracle JHeadstart 10g for Oracle ADF application generator extension for Oracle JDeveloper 10g.
Steve Muench is a consulting product manager for Oracle JDeveloper. In his more than 15 years at Oracle, he has supported and developed Oracle tools and XML technologies and continues to evangelize them. He authored Building Oracle XML Applications (O'Reilly & Associates, 2000) and shares tips and tricks on OTN and his "Dive into BC4J and ADF" Weblog.