JSF Central - AJAX-based Web Development with JSF
JSF Central

 
 Home 
 
 News 
 
 FAQ 
 
 Products 
 
 Articles & Books 
 
 Resources 
AJAX-based Web Development with JSF
 
AJAX-based Web Development with JSF
(continued)
by Mark Schiefelbein
02 Apr 2007 11:30 EDT

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.


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:

  1. The event handler addToCart is called. It creates a new shopping cart item and invokes the addVisualItemToCart method on it.
  2. public void addToCart(ActionEvent event) {
    ...
    UIBackbasePanelGrid item = createCartItem(book);
    this.addVisualItemToCart(item);
    }
  3. The addVisualItemToCart method finds the destination view panel and calls the addChild method to add itself.
  4. public void addVisualItemToCart(UIBackbasePanelGrid item) {
    UIComponent destComponent =
    ComponentUtils.findComponent(
    FacesContext.getCurrentInstance().getViewRoot(),
    "bookCartView:cartDestination");
    ...
    // add the new
    destComponent.addChild(item);
    }
  5. 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.



RSS feed(all feeds)

The Editor's Desk
JSF 2 Group Blog
Inside Facelets
In the Trenches

Sponsored links

Site version 1.83  Report web site problems

Copyright (C) 2003-2007 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Virtua, Inc. is independent of Sun Microsystems, Inc. All other trademarks are the sole property of their respective owners.