Including Ajax Functionality in a Custom JavaServer Faces Component

By Gregory Murray and Jennifer Ball    

What is Ajax?
JavaServer Faces Technology and Ajax
The DOJO Toolkit and Ajax
Using an Ajax-aware Custom Component
Steps to Include Ajax Support in a Custom Component
The Editable Label Example
Creating Necessary JavaScript Functions
Rendering JavaScript Tags With a Custom Renderer
Creating the PhaseListener Class to Handle the Ajax Requests

What is Ajax?

  • JavaScript that allows for interaction with the browser and responding to events
  • The DOM for accessing and manipulating the structure of the HTML of the page
  • XML, which represents the data passed between the server and client.
  • An XMLHttpRequest object for asynchronously exchanging the XML data between the client and the server.

                Figure 1: General Sequence of Ajax Request

  1.  The user generates an event, such as by clicking a button.  This results in a JavaScript call.
  2. An XMLHttpRequest object is created and configured with a request parameter that includes the ID of the component that generated the event and any value that the user might have entered.
  3. The XMLHttpRequest object makes an asynchronous request to the web server.  An object (such as a servlet or listener) receives the request, processes it, and stores any data in the request to the data store.  In the case of Ajax-aware JavaServer Faces components, the object that processes the request is a PhaseListener object.  We'll cover that more later in the document.
  4. The object that processed the request returns an XML document containing any updates that need to go to the client.
  5. The XMLHttpRequest object receives the XML data, processes it, and updates the HTML DOM representing the page with the new data.

JavaServer Faces Technology and Ajax

JavaServer Faces technology is designed to make web application development easier for page authors and developers alike.  The most important feature that logy oSun Java Studio CreatorNetBeans IDE

The DOJO Toolkit and Ajax


Using an Ajax-aware Custom Component

<%@ taglib uri="#" prefix="h" %>

<%@ taglib uri="#" prefix="f" %>

<%@ taglib prefix="dl" uri="#" %>

<dl:dlabel valueBinding="#{} " />


list of Ajax-aware componentsJava Blueprints Solutions CatalogHow to Use the Dynamic Text Component

Steps to Include Ajax Support in A Custom Component

Creating Custom UI Components

  1. Create necessary JavaScript functions, leveraging DOJO as much as possible.
  2. Add code to the component's renderer that will render the JavaScript tags to the page.
  3. Create the PhaseListener class, which handles the Ajax request, interacts with the custom component, and returns an XML document that contains the updated data.

The Editable Label Example

Figure 2: Screen shot of the Editable Label Example

Running the Example

Java Blueprints site

  1. Go to the Java Blueprints site on
  2. Click Documents & files in the right-hand navigation bar.
  3. Select the bpcatalog-ee5(2) directory.
  4. Download the bpcatalog-ee5-ea-0.6-installer.jar.
  5. Run the installer according to the directions on the page from where you downloaded it.

  1. Obtain the Java EE 5 SDK, install it, and start the Sun Java System Application Server.
  2. Add the Ant build tool included in the Application Server to your path.  It's located in the Applications Server installation's lib/ant/bin directory.
  3. Go to <bpcatalog_install>/bp-project/.
  4. Open in a text editor.
  5. Set the javaee.home property to the path of your Application Server installation.
  6. Set the javaee.server.passwordfile property to the fully-qualified path to a file that contains your password.  Follow the instructions in the file.
  7. Save
  8. Go to <bpcatalog_install>/apps/webtier/bp-dynamic-text.
  9. Run ant .
  10. Run ant deploy.
  11. Launch a browser and enter this URL:



The Pieces of the Example
  • index.jsp , a JSP page that contains the dlabel custom JavaServer Faces component tags.
  • confirmation.jsp , a JSP page that displays the updated data of the components.
  • DLabel , which defines the custom component.
  • DLabelRenderer , which renders the markup for the components and the script tags that reference the JavaScript files onto the HTML page.
  • DLabelPhaseListener , which processes the Ajax request, exchanges the data with the server-side object, and returns the XML data to the client.
  • SessionBean , which holds the component data on the server.
  • script.js , a JavaScript file that contains the functions used in this application.
  • styles.css , a stylesheet.
  • dojo.js , the JavaScript file that contains all the JavaScript functions supported by DOJO.

<%@ taglib uri="#" prefix="h" %>

<%@ taglib uri="#" prefix="f" %>

<%@ taglib prefix="dl" uri="#" %>



   <h:panelGrid cellpadding="5" cellspacing="0"

      columns="2" style="margin-bottom: 20px">

 <h:outputText value="Name:" />

        <dl:dlabel size="40" valueBinding="#{} " />

 <h:outputText value="Street:" />

      <dl:dlabel size="40" valueBinding="#{SessionBean.street} " />

       <h:outputText value="City:" />

        <dl:dlabel size="40" valueBinding="#{} " />

 <h:outputText value="State:" />

       <dl:dlabel size="40" valueBinding="#{SessionBean.state} " />

        <h:outputText value="Zip:" />

 <dl:dlabel size="40" valueBinding="#{} " />   






How the Example Works

Figure 3: Sequence of Ajax Request in Editable Label Example

The following steps explain the architecture illustrated in Figure 3:

  1. The renderer outputs the script tag to the page.
    The index.jsp page contains an HTML script tag rendered by the renderer, DLabelRenderer.  While performing the rendering of the components, DLabelRenderer also creates a hash map with all the component IDs and values.

  2. The page obtains the JavaScript from the phase listener.
    A call is made to the URL, faces/ajax-dlabel-script.js, which is mapped to a FacesServlet instance.  This instance processes the DLabelPhaseListener instance, which recognizes the URL and returns the script. js page containing the client-side JavaScript code necessary for the Ajax interactions. When the page loads, it is initialized, and the initialize function is called.  This function registers all the JavaScript events that are needed for rendering the DLabel component tags on the page.
  3. The user enters a value in the field and clicks the Update Me button to update the data.
    After the user clicks a label and enters a value, he or she clicks the Update Me button, which generates an onclick event.  The updateOnServer JavaScript function, which is mapped to this event, creates an XMLHttpRequest object and configures it with the URL to the FacesServlet instance. If the user changed the Name field to Bob, the URL is faces/ajax-dlabel-update&component-id=Name&component-value=Bob.
  4. The XMLHttpRequest object makes a call to FacesServlet, which updates SessionBean.
    After the URL is configured, the XMLHttpRequest object makes a call to the FacesServlet instance, passing the URL faces/ajax-dlabel-update&component-id=Name&component-value=Bob.  The FacesServlet instance processes the DLabelPhaseListener instance that recognizes the URL the XMLHttpRequest object passed to it.   At this point, the FacesServlet instance also updates the value of the name property in SessionBean.
  5. The phase listener loo ks up the component ID included in the URL and stores the new data
      DLabelPhaseListener takes the component ID and value that is included in the URL, looks up the component ID and its value from a hash map, and updates it with the user's input.
  6. The phase listener sends the new data back to the page
    The DLabelPhaseListener instance generates an XML document containing the new component ID and value and returns it to the XMLHttpRequest object.
  7. The XMLHttpRequest object updates the HTML DOM with the new data
    The XMLHttpRequest object calls the XMLHttpRequest callback function.  This function updates the HTML DOM based on the contents of the XML document that was returned, and the response is sent back to the client.


Creating Necessary JavaScript Functions

The JavaScript Resource Center

  • Register JavaScript events on the components
  • Update the data to the server
  • Render extra components (such as the input field and the Update button in our example) and other changes when onmouseover events occur.



bpui.dlabel = new DLabel();

dojo.event.connect("before", window, "onload", bpui.dlabel, "initialize");

initialize ajax-commons.js (as plain text)

Registering JavaScript Events on the Components

onloadinitializedlabelPlainTextgetElementsByClassRendering JavaScript Tags with a Custom RendererclassinitializeupdateItem
                      // key in on the dlabel components by the                       
function getElementsByClass(className){ var found = []; var elements= document.all ? document.all : document.getElementsByTagName("*"); for (var i=0; i < elements.length; i++){ // TODO: Handle multiple classnames if (elements[i].className==className) { found.push(elements[i]); } } return found; } this.initialize = function() { var pageElements = getElementsByClass('dlabelPlainText'); for (var loop = 0; loop < pageElements.length; loop++) { var pageElement = pageElements[loop]; var itemId = pageElement.getAttribute("id"); var itemValue = pageElement.firstChild.nodeValue; updateItem(itemId, itemValue); } }

Updating Data on the Server


function updateOnServer(itemId, itemValue) {

   var bindArgs = {

  url: "faces/ajax-dlabel-update",

    method: "post",

     content: {"component-id": itemId,

             "component-value":itemValue} ,

 mimetype: "text/xml",

       load: function(type, data) {


        } ,


   } ;

  • url: This is the URL that the XMLHttpRequest object passes to the phase listener, which will use it to create an XML document with the component IDs and values.
  • method: This indicates the HTTP method to use when the function is called.  In this case, we want to use POST to post data to the server.
  • content: This attribute contains the ID of the component the user chose to edit as well as the value the user entered into the text field.
  • mimetype: Indicates the MIME type of the content to be passed from the phase listener
  • load: Specifies the function that will be invoked after the XML data is received.


function processUpdateResponse(responseXML) {


    // sync the changes with what is on the server

    var compId =



    var compValue = "";



    compValue = responseXML.getElementsByTagName("component-value")


    var status = responseXML.


    updateItem(compId, compValue);


Rendering JavaScript Tags With a Custom Renderer



private void renderScriptOnce(ResponseWriter writer,

  UIComponent component, FacesContext context)

    throws IOException {

   Map requestMap =


   Boolean scriptRendered =



   if (scriptRendered == Boolean.TRUE) {




   requestMap.put(RENDERED_SCRIPT_KEY, Boolean.TRUE);





writer.startElement("script", component);

writer.writeAttribute("type", "text/javascript", null);

String ssrc = "faces/ajax-dlabel-script.js";

writer.writeAttribute("src", ssrc, null);





HashMap bindings =


if(bindings == null) {

     bindings = new HashMap();

   session.setAttribute("dBindings", bindings);



synchronized(bindings) {

     bindings.put(baseId, valueBinding);



DLabelRendererdivdivdivdlabelPlainTextRegistering JavaScript Events on the Componentsinitialize

writer.startElement("div", component);

writer.writeAttribute("id", baseId, "id");

writer.writeAttribute("class", "dlabelPlainText", null);




Creating the PhaseListener Class to Handle the Ajax Requests



  • Renders the JavaScript to the page based on the URL passed to it
  • Gets the component ID and new value from the request, edits the XML file with the new value, and puts the file into the response.


private static final String SCRIPT_VIEW_ID = "ajax-dlabel-script.js";

private static final String DOJO_VIEW_ID = "dojo.js";

private static final String CSS_VIEW_ID = "ajax-dlabel.css";

private static final String UPDATE_STATE_ID = "ajax-dlabel-update";


public void afterPhase(PhaseEvent event) {

        String rootId =


  if(rootId.endsWith(SCRIPT_VIEW_ID)) {


                       "script.js", "text/javascript");





Rendering the JavaScript to the Page



Getting the User Input and Creating the XML File with the New Data


private static final String UPDATE_STATE_ID = "ajax-dlabel-update";


public void afterPhase(PhaseEvent event) {


 }  else if (rootId.indexOf(UPDATE_STATE_ID) != -1) {






FacesContext context = event.getFacesContext();

HttpServletResponse response =



Object object = context.getExternalContext().getRequest();

if (!(object instanceof HttpServletRequest)) {



HttpServletRequest request = (HttpServletRequest)object;

HttpSession session = request.getSession();

String compId = request.getParameter("component-id");

String compValue = request.getParameter("component-value");



ValueExpression valueBinding = (ValueExpression)


valueBinding.setValue(context.getELContext(), compValue);


String message = "success";

StringBuffer sb = new



sb.append("<component-id>" + compId + "</component-id>");

sb.append("<component-value>" + compValue + "</component-value>");

sb.append("<status>" + message + "</status>");


try {


        response.setHeader("Cache-Control", "no-cache");


}  catch (IOException iox) {


    "DLabelPhaseListener error writing Ajax response : "

            + iox);




For More Information

JavaScript Resource Center
JavaServer Faces Technology
Java Blueprints Solutions Catalog
DOJO JavaScript Toolkit
Left Curve
Java SDKs and Tools
Right Curve
Left Curve
Java Resources
Right Curve