In the following sections I only focus on the presentation layer and discuss the UI component model, events, and state management.
The UI Component Model
Using the Backbase - AJAX JSF Edition, the interface is distributed across
the client and server. The server side is an extended MyFaces runtime. The
client side is the Backbase AJAX engine. Component instances are instantiated
both on the server and the client. On the server, the instances are created
through a JSF tag. The JSF tag not only creates the server-side component,
but also automatically generates code for the client-side instance. The client-side
instance is a Backbase control that is managed client-side by the Backbase
AJAX engine.
To explore the server-side and client-side component model, look at the listgrid component, a feature-rich control for viewing and editing tabular data (see Figure 4).

Figure 4. Rich AJAX listgrid widget.
First look at the server side. The following code snippet from the JSP file
shows how the bjs:listGrid JSF tag instantiates a listgrid component.
The attributes of the grid define the data binding, a pager control to move
to previous and next pages as well as events for sorting and drag-and-drop support
of book details from the grid to the shopping cart.
<bjs:listGrid binding="#{bookDBAO.listgrid}"
pageSize="10"
pagerOnTop="false"
pagerOnBottom="false"
value="#{bookDBAO.books}"
var="book" sortListener="#{bookDBAO.sort}"
selectListener="#{bookDBAO.select}"
dragListener="#{bookDBAO.drag}"
dragSymbol="<img src='style/gfx/book.gif'/>">
<bjs:column>
<f:facet name="header">
<bjs:outputText value="#{bundle.ItemTitle}" />
</f:facet>
<bjs:outputText value="#{book.title}" />
</bjs:column>
</bjs:listGrid>
When the JSP is executed, the Backbase JSF listgrid instance is created on
the server. Furthermore, a corresponding client-side component, b:listgrid,
is rendered. Figure 5 shows the listgrid instance displayed in Backbase's Run-time
Developer Tool.

Figure 5. Client-side AJAX representation of the listgrid
widget shown in Backbase's Run-time Developer Tool.
The b:listgrid is managed by the client-side Backbase AJAX engine. The engine manages interaction and events and renders the grid to the browser DOM. The runtime debugger can also be used to look at the standard XHTML generated by the Backbase engine, as shown in Figure 6.

Figure 6. Client-side XHTML representation of the listgrid widget.
The example shows how the Backbase AJAX engine introduces a client-side component
model with the same expressiveness as the JSF server-side model. Instead of
static HTML, the client interface is made up of rich client-side controls. The
Backbase - AJAX JSF Edition complements the JSF server-side UI component model
with an analogous client-side model.
Navigation and Events
Now that I've discussed the component models, let's examine the shopping cart
interaction to demonstrate event handling and partial page refreshing. The basic
interaction consists of a user selecting a book and putting it in the shopping
cart.
In the traditional bookstore, users click an Add to Cart link. The click takes them to a new page that shows the contents of the shopping cart. In the AJAX-based store, clicking the Add to Cart link results in a partial page refresh: both catalog and cart are shown on one page. In response to the click, an event is fired that results in the shopping cart being updated without any reloading of the page.
More specifically, the page is split into areas that can be updated dynamically. This is done by defining panel groups in the file mainpanel.jsp. In the following snippet, note the definition of the panel that partially loads the updated shopping cart from bookcart.jsp.
<bjs:application skin="bookstore">
...
<table class="page">
<tbody>
<tr>
<td class="page-left"/>
<td class="page-center">
<bjs:panelGroup id="mainpanel-title">
<bjs:graphicImage url="gfx/logo.png"/>
</bjs:panelGroup>
<bjs:panelGroup id="mainpanel-top">
<%@include file="bookcategories.jsp"%>
</bjs:panelGroup>
<bjs:panelGroup id="mainpanel-bottom">
<bjs:panelGrid columns="2" styleClass="mainpanel-bottom"
columnClasses="mainpanel-bottomleft, mainpanel-bottomright">
<bjs:panelGroup id="mainpanel-bottomleft">
<%@include file="bookcatalog.jsp"%>
</bjs:panelGroup>
<bjs:panelGroup>
<%@include file="bookcart.jsp"%>
</bjs:panelGroup>
</bjs:panelGrid>
</bjs:panelGroup>
...
</bjs:application>
You now have a target destination for partial page updates. When the shopping cart content changes, the result of the bookcart.jsp file will be rendered into the pre-defined bjs:panelGroup.
The interaction is triggered when the user adds a book to the cart. The button component bjs:commandButton id="add" has been configured to trigger the server-side event bookDBAO.addToCart, using the standard JSF event handling mechanism as shown in the following code snippet:
<bjs:commandButton id="add"
value="#{bundle.CartAdd}"
actionListener="#{bookDBAO.addToCart}"/>
The following steps explain how the event handler is executed and partially updates the shopping cart through the server-side backing bean. The code in BookDBAO.java is executed in three steps:
- The event handler
addToCart is called. It creates a new shopping
cart item and invokes the addVisualItemToCart method on it.
public void addToCart(ActionEvent event) {
...
UIBackbasePanelGrid item = createCartItem(book);
this.addVisualItemToCart(item);
}
- The
addVisualItemToCart method finds the destination view panel
and calls the addChild method to add itself.
public void addVisualItemToCart(UIBackbasePanelGrid item) {
UIComponent destComponent =
ComponentUtils.findComponent(
FacesContext.getCurrentInstance().getViewRoot(),
"bookCartView:cartDestination");
...
// add the new
destComponent.addChild(item);
}
- The
addChild method of the view panelGroup executes
a partial update of the page and shows the new item in the shopping cart.
The example shows how the component-based event mechanism of JSF has been turned
into a two-way process. Requests are fine-grained per component events sent
from the client to the server. The Backbase - AJAX JSF Edition introduces responses
that are partial page updates sent from the server to the client.
State Management
In the previous sections, I discussed the presence of a component model client-side
and server-side. The state of each model is managed as a tree, similar to the
DOM tree of the browser. The tree contains all components hierarchically. The
state of each component is managed through attributes.
Figure 7 shows the book categorization. The categorization is implemented
as a UI control with a server-side and a client-side instance. The Backbase
- AJAX JSF Edition contains a state synchronization mechanism based on attributes.
The interface developer only needs to select which attributes need to be synchronized.
In the case of the book classification, the disabled, value,
and size attributes are automatically kept in synch between the
client and the server.

Figure 7. Attribute synchronization while browsing book categories.
The interactivity and responsiveness of AJAX applications requires state changes managed on both the client and the server. To make this possible, client and server states need to be synchronized. The Backbase - AJAX JSF Edition contains an attribute-based state synchronization mechanism.
Conclusion
This article shows how you can bring together JSF and AJAX to provide a powerful, well-integrated and standards-based framework for the development of rich web interfaces. When combined, JSF and AJAX provide a powerful, well-integrated, and standards-based framework for the development of rich web interfaces. They work together to form a formal model for rich and interactive UI components, as well as a fine-grained event-based navigation mechanism and integrated state management across the client and server.
The ajaxified Duke's Bookstore sample demonstrates how easy it is to build a compelling
web interface using JSF and AJAX. An online version of Duke's Bookstore is available
at the Backbase Duke's Bookstore site.
You can also download a trial version
of the Backbase - AJAX JSF Edition.
Page:
1
2