ADF productivity boost for Ajax enabled Master – Detail web pages

Last time I promised a side-by-side .Net vs ADF comparison of Ajax enabled Master-Detail web pages.
So in this article, I’m going to compare the two and show how you can increase productivity by using ADF.


This is the screenshot of the .Net example we are going to implement. Note that I’m focusing on functionality, not skinning here.

Asp.Net master detail form example

The form implements the following use cases:

  • User can filter master records by clicking one of the A-Z buttons (names starts with the selected letter)
  • Selecting the master record loads the detail record(s)*
*I find the .Net sample app a bit out of place, as it is not true master detail app. If you take a look a the DAL, you’ll see that Customer-Contact is 1-1 relation, since ContactName is simply a property of a Customer. So the example is really not implementing Master – detail, according to Wikipedia. But still, it’s a MSDN published, reference asp.net master-detail implementation.

Please read the article to learn how the .Net application is implemented. The general idea is:
  • Implement DAL in business objects
  • Wrap DAL in data service
  • Create an asp.net web page, defining template for master and detail view
  • Load and show data by using MS Ajax library
Implementing the example in ADF


Note: the sources for the resulting ADF application are available at google code: svn checkout http://adfcommunity.googlecode.com/svn/trunk/AdfMasterDetailDemo adfcommunity-read-only

1. Model
To implement Model (called Data Access Layer in .Net), we start by Creating Business Components from Tables. This automatically creates the model, with all CRUD method for us.
Note: since ADF sample is based on Oracle Database, I will use hr schema with Departments 1 – * Employees schema.

Model (DAL) in ADF
If you are coming from .Net this screenshot is a bit confusing. But for now, you should keep in mind that Business Components compare to Ado.Net datasets or Entity Framework Entities.
Coding so far: 0
Now let’s implement what’s required for first use case: filtering by starts with criteria.
We define view criteria for Starts with query
Then, by simply marking a checkbox we implement a custom class for our view object. Unlike .Net’s partial class, in ADF overs full control and customization of data objects! And then we add a custom method to our ViewObject:
public void queryByStartsWithParam(String startsWith) {
  ViewCriteria vc=getViewCriteria("startsWithCriteria");
  ((Row)vc.getRows().toArray()[0]).setAttribute("DepartmentName",startsWith);
  applyViewCriteria(vc);
  executeQuery();
}

And finally, we expose our custom method to clients
Expose custom method to clients

Coding so far: 6 LOC


2. User interface
For general layout I created a page template which you’ll find in source files. For those of you who don’t know ADF suffices to say page template is similar to asp.net master pages. I didn’t bother to create exactly the same layout, but it’s fairly similar.

We’ll start by adding a panelSplitter to content facet, since it’s very useful for master-detail pages. Then, we simply drag and drop DepartmentsView1 from DataControls to the panelSplitter, we create a table for our master data.
<af:table value="#{bindings.DepartmentsView1.collectionModel}"
    var="row"
    rows="#{bindings.DepartmentsView1.rangeSize}"
    emptyText="#{bindings.DepartmentsView1.viewable ? 'No data to display.' : 'Access Denied.'}"
    fetchSize="#{bindings.DepartmentsView1.rangeSize}"
    rowBandingInterval="0"
    selectedRowKeys="#{bindings.DepartmentsView1.collectionModel.selectedRow}"
    selectionListener="#{bindings.DepartmentsView1.collectionModel.makeCurrent}"
    rowSelection="single" id="t1"
    horizontalGridVisible="false"
    verticalGridVisible="false"
    inlineStyle="border-style:none;margin-left:50px;"
    contentDelivery="immediate" displayRow="selected">
      <af:column sortProperty="DepartmentName" sortable="false"
                  headerClass="noHeader" width="400" id="c1">
        
          
          
          <af:outputText value="#{row.DepartmentName}" id="ot2"
                                         styleClass="listText"/>
        
    


Note that the above code is auto generated for us. We just modify it a bit to suite our needs (mostly design related).
Next, we add detail form. We drag and drop Employees detail view from the Data Controls to the second facet of the panelSplitter and choos ADF form. We also add navigation buttons, just because we can. Here we change nothing but decorate our form with custom css style.

Creating details form is a simple drag and drop operation.

Coding so far: 6 LOC + a bit JSF tweaking. So where could this get us? Let’s see.

Well, turns out we built a completely functional, Ajax enabled real Master – Detail web page. When you select a record in master table the details are loaded using Ajax. Also, because this is true 1-* Master – Detail, we added navigation buttons to our detail records. How cool is that?
And please note, the 6 LOC we wrote weren’t even used by now. So let’s use it and finish the example.


First we’ll bind our web page to the queryByStartsWithParam method:

Binding web page to custom function

Then we add filter buttons:


<af:commandButton text="A" id="commandButton1"
styleClass="bar"
actionListener="#{bindings.queryByStartsWithParam.execute}"
partialSubmit="true">
<af:setActionListener from="A"
to="#{bindings.startsWith.inputValue}"/>

Note After adding all the buttons and cofiguring them to trigger partial Ajax page request, we got only one more thing to do: add the “Selected Departments” label:

<af:outputText value="Selected customers: #{bindings.startsWith.inputValue}"
id="ot6"
inlineStyle="color:#76b7d7; font-size:1.4em; font-weight:bold;"
partialTriggers="t1"/>

Putting it all together:
ADF master detail sample.

2. That’s not all Folks!
You know, the .Net example is fine and all, but it doesn’t even mention two other issues:

  • persisting changes and
  • data validation
Sure, those are important building blocks. So important in fact, that MSDN runs another article just on saving changes back to the server. More technology, more code.
But, we can do it all with just two simple drag and drops! Let me show you how:
in the Data Controls, we’ll find two operations: commit and rollback. Again, drag and drop them to our page and ADF will create buttons for us.
Commit and Rollback operations become…
… Commit and Rollback buttons!
Coding so far: 6 LOC. And yes, it’s hard to believe, but that really is all we need to do to save the changes back to the database. Or discard them if we made a mistake.

And again, just because we can, how about adding regular expression validation for email format?
Adding regexp validation for email address.
And that’s about it. Nothing else. When we try to save an invalid email address we get:
Out of the box validation
Coding so far: 6 LOC, a few template tweaks and a validation rule. Can you top that?

3. Summary
As we can see, we  implemented a fully functional, Ajax enabled Master detail Web page with only 6 lines of code and some auto-generated layout tweaking.

When project just begins in .Net, finally displaying read-only web-pages, it’s almost finished in ADF, since data validation and persistence are an essential parts of the framework.

No extra knowledge of different platforms, technologies or APIs was necessary (Javascript, DOM, Jquery, MS Ajax library..).

Consequently, ADF applications are cheap to maintain since codebase and technology scope is smaller compared to other platforms.

The winner? ADF, hands down.

Click on a tab to select how you'd like to leave your comment

Leave a Reply

Your email address will not be published. Required fields are marked *