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)*
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
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
![]() |
| Model (DAL) in ADF |
![]() |
| We define view criteria for Starts with query |
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}"/>
<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
![]() |
| Commit and Rollback operations become… |
![]() |
| … Commit and Rollback buttons! |
![]() |
| Adding regexp validation for email address. |
![]() |
| Out of the box validation |
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.














