Using Ajax with Jakarta Faces Technology

This chapter describes using Ajax functionality in Jakarta Faces web applications. Ajax is an acronym for Asynchronous JavaScript and XML, a group of web technologies that enable creation of dynamic and highly responsive web applications. Using Ajax, web applications can retrieve content from the server without interfering with the display on the client. In the Jakarta EE platform, Jakarta Faces technology provides built-in support for Ajax.

Overview of Ajax

Early web applications were created mostly as static web pages. When a static web page is updated by a client, the entire page has to reload to reflect the update. In effect, every update needs a page reload to reflect the change. Repetitive page reloads can result in excessive network access and can impact application performance. Technologies such as Ajax were created to overcome these deficiencies.

Ajax refers to JavaScript and XML, technologies that are widely used for creating dynamic and asynchronous web content. While Ajax is not limited to JavaScript and XML technologies, more often than not they are used together by web applications. The focus of this tutorial is on using JavaScript based Ajax functionality in Jakarta Faces web applications.

JavaScript is a dynamic scripting language for web applications. It allows users to add enhanced functionality to user interfaces and allows web pages to interact with clients asynchronously. JavaScript runs mainly on the client side (as in a browser) and thereby reduces server access by clients.

When a JavaScript function sends an asynchronous request from the client to the server, the server sends back a response that is used to update the page’s Document Object Model (DOM). This response is often in the format of an XML document. The term Ajax refers to this interaction between the client and server.

The server response need not be in XML only; it can also be in other formats, such as JSON (see Introduction to JSON and https://www.json.org/). This tutorial does not focus on the response formats.

Ajax enables asynchronous and partial updating of web applications. Such functionality allows for highly responsive web pages that are rendered in near real time. Ajax-based web applications can access server and process information and can also retrieve data without interfering with the display and rendering of the current web page on a client (such as a browser).

Some of the advantages of using Ajax are as follows:

  • Form data validation in real time, eliminating the need to submit the form for verification

  • Enhanced functionality for web pages, such as user name and password prompts

  • Partial update of the web content, avoiding complete page reloads

Using Ajax Functionality with Jakarta Faces Technology

Ajax functionality can be added to a Jakarta Faces application in one of the following ways:

  • Adding the required JavaScript code to an application

  • Using the built-in Ajax resource library

In earlier releases of the Jakarta EE platform, Jakarta Faces applications provided Ajax functionality by adding the necessary JavaScript to the web page. In the Jakarta EE platform, standard Ajax support is provided by a built-in JavaScript resource library.

With the support of this JavaScript resource library, Jakarta Faces standard UI components, such as buttons, labels, or text fields, can be enabled for Ajax functionality. You can also load this resource library and use its methods directly from within the managed bean code. The next sections of the tutorial describe the use of the built-in Ajax resource library.

In addition, because the Jakarta Faces technology component model can be extended, custom components can be created with Ajax functionality.

The tutorial examples include an Ajax version of the guessnumber application, ajaxguessnumber. See The ajaxguessnumber Example Application for more information.

The Ajax specific f:ajax tag and its attributes are explained in the next sections.

Using Ajax with Facelets

As mentioned in the previous section, Jakarta Faces technology supports Ajax by using a built-in JavaScript resource library that is provided as part of the Jakarta Faces core libraries. This built-in Ajax resource can be used in Jakarta Faces web applications in one of the following ways.

  • By using the f:ajax tag along with another standard component in a Facelets application. This method adds Ajax functionality to any UI component without additional coding and configuration.

  • By using the JavaScript API method jsf.ajax.request() directly within the Facelets application. This method provides direct access to Ajax methods and allows customized control of component behavior.

  • By using the <h:commandScript> component to execute arbitrary server-side methods from a view. The component generates a JavaScript function with a given name that when invoked, in turn invokes, a given server-side method via Ajax.

Using the f:ajax Tag

The f:ajax tag is a Jakarta Faces core tag that provides Ajax functionality to any regular UI component when used in conjunction with that component. In the following example, Ajax behavior is added to an input component by including the f:ajax core tag:

<h:inputText value="#{bean.message}">
    <f:ajax />
</h:inputText>

In this example, although Ajax is enabled, the other attributes of the f:ajax tag are not defined. If an event is not defined, the default action for the component is performed. For the inputText component, when no event attribute is specified, the default event is valueChange. Attributes of the f:ajax Tag lists the attributes of the f:ajax tag and their default actions.

Attributes of the f:ajax Tag
Name Type Description

disabled

jakarta.el.ValueExpression that evaluates to a Boolean

A Boolean value that identifies the tag status. A value of true indicates that the Ajax behavior should not be rendered. A value of false indicates that the Ajax behavior should be rendered. The default value is false.

event

jakarta.el.ValueExpression that evaluates to a String

A String that identifies the type of event to which the Ajax action will apply. If specified, it must be one of the events supported by the component. If not specified, the default event (the event that triggers the Ajax request) is determined for the component. The default event is action for jakarta.faces.component.ActionSource components and valueChange for jakarta.faces.component.EditableValueHolder components.

execute

jakarta.el.ValueExpression that evaluates to an Object

A Collection that identifies a list of components to be executed on the server. If a literal is specified, it must be a space-delimited String of component identifiers and/or one of the keywords. If a ValueExpression is specified, it must refer to a property that returns a Collection of String objects. If not specified, the default value is @this.

immediate

jakarta.el.ValueExpression that evaluates to a Boolean

A Boolean value that indicates whether inputs are to be processed early in the lifecycle. If true, behavior events generated from this behavior are broadcast during the Apply Request Values phase. Otherwise, the events will be broadcast during the Invoke Application phase.

listener

jakarta.el.MethodExpression

The name of the listener method that is called when a jakarta.faces.event.AjaxBehaviorEvent has been broadcast for the listener.

onevent

jakarta.el.ValueExpression that evaluates to a String

The name of the JavaScript function that handles UI events.

onerror

jakarta.el.ValueExpression that evaluates to a String

The name of the JavaScript function that handles errors.

render

jakarta.el.ValueExpression that evaluates to an Object

A Collection that identifies a list of components to be rendered on the client. If a literal is specified, it must be a space-delimited String of component identifiers and/or one of the keywords. If a ValueExpression is specified, it must refer to a property that returns a Collection of String objects. If not specified, the default value is @none.

The keywords listed in Execute and Render Keywords can be used with the execute and render attributes of the f:ajax tag.

Execute and Render Keywords
Keyword Description

@all

All component identifiers

@form

The form that encloses the component

@none

No component identifiers

@this

The element that triggered the request

Note that when you use the f:ajax tag in a Facelets page, the JavaScript resource library is loaded implicitly. This resource library can also be loaded explicitly as described in Loading JavaScript as a Resource.

Sending an Ajax Request

To activate Ajax functionality, the web application must create an Ajax request and send it to the server. The server then processes the request.

The application uses the attributes of the f:ajax tag listed in attributes of the f:ajax tag to create the Ajax request. The following sections explain the process of creating and sending an Ajax request using some of these attributes.

Behind the scenes, the jsf.ajax.request() method of the JavaScript resource library collects the data provided by the f:ajax tag and posts the request to the Jakarta Faces lifecycle.

Using the event Attribute

The event attribute defines the event that triggers the Ajax action. Some of the possible values for this attribute are click, keyup, mouseover, focus, and blur.

If not specified, a default event based on the parent component will be applied. The default event is action for jakarta.faces.component.ActionSource components, such as a commandButton, and valueChange for jakarta.faces.component.EditableValueHolder components, such as inputText. In the following example, an Ajax tag is associated with the button component, and the event that triggers the Ajax action is a mouse click:

<h:commandButton id="submit" value="Submit">
    <f:ajax event="click" />
</h:commandButton>
<h:outputText id="result" value="#{userNumberBean.response}" />
You may have noticed that the listed events are very similar to JavaScript events. In fact, they are based on JavaScript events, but do not have the on prefix.

For a command button, the default event is click, so you do not actually need to specify event="click" to obtain the desired behavior.

Using the execute Attribute

The execute attribute defines the component or components to be executed on the server. The component is identified by its id attribute. You can specify more than one executable component. If more than one component is to be executed, specify a space-delimited list of components.

When a component is executed, it participates in all phases of the request-processing lifecycle except the Render Response phase.

The execute attribute value can also be a keyword, such as @all, @none, @this, or @form. The default value is @this, which refers to the component within which the f:ajax tag is nested.

The following code specifies that the h:inputText component with the id value of userNo should be executed when the button is clicked:

<h:inputText id="userNo"
             title="Type a number from 0 to 10:"
             value="#{userNumberBean.userNumber}">
    ...
</h:inputText>
<h:commandButton id="submit" value="Submit">
    <f:ajax event="click" execute="userNo" />
</h:commandButton>

Using the immediate Attribute

The immediate attribute indicates whether user inputs are to be processed early in the application lifecycle or later. If the attribute is set to true, events generated from this component are broadcast during the Apply Request Values phase. Otherwise, the events will be broadcast during the Invoke Application phase.

If not defined, the default value of this attribute is false.

Using the listener Attribute

The listener attribute refers to a method expression that is executed on the server side in response to an Ajax action on the client. The listener’s jakarta.faces.event.AjaxBehaviorListener.processAjaxBehavior method is called once during the Invoke Application phase of the lifecycle. In the following code from the reservation example application (see The reservation Example Application), a listener attribute is defined by an f:ajax tag, which refers to a method from the bean:

<f:ajax event="change" render="total"
        listener="#{reservationBean.calculateTotal}"/>

Whenever either the price or the number of tickets ordered changes, the calculateTotal method of ReservationBean recalculates the total cost of the tickets and displays it in the output component named total.

Monitoring Events on the Client

To monitor ongoing Ajax requests, use the onevent attribute of the f:ajax tag. The value of this attribute is the name of a JavaScript function. Jakarta Faces calls the onevent function at each stage of the processing of an Ajax request: begin, complete, and success.

When calling the JavaScript function assigned to the onevent property, Jakarta Faces passes a data object to it. The data object contains the properties listed in Properties of the onevent Data Object.

Properties of the onevent Data Object
Property Description

responseXML

The response to the Ajax call in XML format

responseText

The response to the Ajax call in text format

responseCode

The response to the Ajax call in numeric code

source

The source of the current Ajax event: the DOM element

status

The status of the current Ajax call: begin, complete, or success

type

The type of the Ajax call: event

By using the status property of the data object, you can identify the current status of the Ajax request and monitor its progress. In the following example, monitormyajaxevent is a JavaScript function that monitors the Ajax request sent by the event:

<f:ajax event="click" render="statusmessage" onevent="monitormyajaxevent"/>

Handling Errors

Jakarta Faces handles Ajax errors through use of the onerror attribute of the f:ajax tag. The value of this attribute is the name of a JavaScript function.

When there is an error in processing a Ajax request, Jakarta Faces calls the defined onerror JavaScript function and passes a data object to it. The data object contains all the properties available for the onevent attribute and, in addition, the following properties:

  • description

  • errorName

  • errorMessage

The type is error. The status property of the data object contains one of the valid error values listed in Valid Error Values for the Data Object status Property.

Valid Error Values for the Data Object status Property
Values Description

emptyResponse

No Ajax response from server.

httpError

One of the valid HTTP errors: request.status==null or request.status==undefined or request.status<200 or request.status>=300.

malformedXML

The Ajax response is not well formed.

serverError

The Ajax response contains an error element.

In the following example, any errors that occurred in processing the Ajax request are handled by the handlemyajaxerror JavaScript function:

<f:ajax event="click" render="errormessage" onerror="handlemyajaxerror"/>

Receiving an Ajax Response

After the application sends an Ajax request, it is processed on the server side, and a response is sent back to the client. As described earlier, Ajax allows for partial updating of web pages. To enable such partial updating, Jakarta Faces technology allows for partial processing of the view. The handling of the response is defined by the render attribute of the f:ajax tag.

Similar to the execute attribute, the render attribute defines which sections of the page will be updated. The value of a render attribute can be one or more component id values, one of the keywords @this, @all, @none, or @form, or an EL expression. In the following example, the render attribute identifies an output component to be displayed when the button component is clicked (the default event for a command button):

<h:commandButton id="submit" value="Submit">
    <f:ajax execute="userNo" render="result" />
</h:commandButton>
<h:outputText id="result" value="#{userNumberBean.response}" />
Behind the scenes, once again the jsf.ajax.request() method handles the response. It registers a response-handling callback when the original request is created. When the response is sent back to the client, the callback is invoked. This callback automatically updates the client-side DOM to reflect the rendered response.

Ajax Request Lifecycle

An Ajax request varies from other typical Jakarta Faces requests, and its processing is also handled differently by the Jakarta Faces lifecycle.

As described in Partial Processing and Partial Rendering, when an Ajax request is received, the state associated with that request is captured by the jakarta.faces.context.PartialViewContext. This object provides access to information such as which components are targeted for processing/rendering. The processPartial method of PartialViewContext uses this information to perform partial component tree processing and rendering.

The execute attribute of the f:ajax tag identifies which segments of the server-side component tree should be processed. Because components can be uniquely identified in the Jakarta Faces component tree, it is easy to identify and process a single component, a few components, or a whole tree. This is made possible by the visitTree method of the UIComponent class. The identified components then run through the Jakarta Faces request lifecycle phases.

Similar to the execute attribute, the render attribute identifies which segments of the Jakarta Faces component tree need to be rendered during the render response phase.

During the render response phase, the render attribute is examined. The identified components are found and asked to render themselves and their children. The components are then packaged up and sent back to the client as a response.

Grouping of Components

The previous sections describe how to associate a single UI component with Ajax functionality. You can also associate Ajax with more than one component at a time by grouping them together on a page. The following example shows how a number of components can be grouped by using the f:ajax tag:

<f:ajax>
    <h:form>
        <h:inputText id="input1" value="#{user.name}"/>
        <h:commandButton id="Submit"/>
    </h:form>
</f:ajax>

In the example, neither component is associated with any Ajax event or render attributes yet. Therefore, no action will take place in case of user input. You can associate the above components with an event and a render attribute as follows:

<f:ajax event="click" render="@all">
    <h:form>
        <h:inputText id="input1" value="#{user.name}"/>
        <h:commandButton id="Submit"/>
    </h:form>
</f:ajax>

In the updated example, when the user clicks either component, the updated results will be displayed for all components. You can further fine-tune the Ajax action by adding specific events to each of the components, in which case Ajax functionality becomes cumulative. Consider the following example:

<f:ajax event="click" render="@all">
    ...
    <h:commandButton id="Submit">
        <f:ajax event="mouseover"/>
    </h:commandButton>
    ...
</f:ajax>

Now the button component will fire an Ajax action in case of a mouseover event as well as a mouse-click event.

Loading JavaScript as a Resource

The JavaScript resource file bundled with Jakarta Faces technology is named jsf.js and is available in the jakarta.faces library. This resource library supports Ajax functionality in Jakarta Faces applications.

If you use the f:ajax tag on a page, the jsf.js resource is automatically delivered to the client. It is not necessary to use the h:outputScript tag to specify this resource. You may want to use the h:outputScript tag to specify other JavaScript libraries.

To use a JavaScript resource directly with a UIComponent, you must explicitly load the resource as described in either of the following topics:

Using JavaScript API in a Facelets Application

To use the JavaScript resource API directly in a web application, such as a Facelets page:

  1. Identify the default JavaScript resource for the page with the help of the h:outputScript tag.

    For example, consider the following section of a Facelets page:

    <h:form>
        <h:outputScript name="jsf.js" library="jakarta.faces" target="head"/>
    </h:form>

    Specifying the target as head causes the script resource to be rendered within the head element on the HTML page.

  2. Identify the component to which you would like to attach the Ajax functionality.

  3. Add the Ajax functionality to the component by using the JavaScript API. For example, consider the following:

    <h:form>
        <h:outputScript name="jsf.js" library="jakarta.faces" target="head">
        <h:inputText id="inputname" value="#{userBean.name}"/>
        <h:outputText id="outputname" value="#{userBean.name}"/>
        <h:commandButton id="submit" value="Submit"
                         onclick="jsf.ajax.request(this, event,
                                  {execute:'inputname',render:'outputname'});
                                  return false;" />
    </h:form>

    The jsf.ajax.request method takes up to three parameters that specify source, event, and options. The source parameter identifies the DOM element that triggered the Ajax request, typically this. The optional event parameter identifies the DOM event that triggered this request. The optional options parameter contains a set of name/value pairs from Possible Values for the Options Parameter.

    Possible Values for the Options Parameter
    Name Value

    execute

    A space-delimited list of client identifiers or one of the keywords listed in Execute And Render Keywords. The identifiers reference the components that will be processed during the Execute phase of the lifecycle.

    render

    A space-delimited list of client identifiers or one of the keywords listed in Execute And Render Keywords. The identifiers reference the components that will be processed during the render phase of the lifecycle.

    onevent

    A String that is the name of the JavaScript function to call when an event occurs.

    onerror

    A String that is the name of the JavaScript function to call when an error occurs.

    params

    An object that may include additional parameters to include in the request.

    If no identifier is specified, the default assumed keyword for the execute attribute is @this, and for the render attribute it is @none.

    You can also place the JavaScript method in a file and include it as a resource.

Using the @ResourceDependency Annotation in a Bean Class

Use the jakarta.faces.application.ResourceDependency annotation to cause the bean class to load the default jsf.js library.

To load the Ajax resource from the server side:

  1. Use the jsf.ajax.request method within the bean class.

    This method is usually used when creating a custom component or a custom renderer for a component.

    The following example shows how the resource is loaded in a bean class:

    @ResourceDependency(name="jsf.js" library="jakarta.faces" target="head")

The ajaxguessnumber Example Application

To demonstrate the advantages of using Ajax, revisit the guessnumber example from Introduction to Facelets. If you modify this example to use Ajax, the response need not be displayed on the response.xhtml page. Instead, an asynchronous call is made to the bean on the server side, and the response is displayed on the originating page by executing just the input component rather than by form submission.

The source code for this application is in the jakartaee-examples/tutorial/web/faces/ajaxguessnumber/ directory.

The ajaxguessnumber Source Files

The changes to the guessnumber application occur in two source files.

The ajaxgreeting.xhtml Facelets Page

The Facelets page for ajaxguessnumber, ajaxgreeting.xhtml, is almost the same as the greeting.xhtml page for the guessnumber application:

<h:head>
    <h:outputStylesheet library="css" name="default.css"/>
    <title>Ajax Guess Number Facelets Application</title>
</h:head>
<h:body>
    <h:form id="AjaxGuess">
        <h:graphicImage value="#{resource['images:wave.med.gif']}"
                        alt="Duke waving his hand"/>
        <h2>
            Hi, my name is Duke. I am thinking of a number from
            #{dukesNumberBean.minimum} to #{dukesNumberBean.maximum}.
            Can you guess it?
        </h2>
        <p>
            <h:inputText id="userNo"
                         title="Enter a number from 0 to 10:"
                         value="#{userNumberBean.userNumber}">
                <f:validateLongRange minimum="#{dukesNumberBean.minimum}"
                                     maximum="#{dukesNumberBean.maximum}"/>
            </h:inputText>

            <h:commandButton id="submit" value="Submit">
                <f:ajax execute="userNo" render="outputGroup" />
            </h:commandButton>
        </p>
        <p>
            <h:panelGroup layout="block" id="outputGroup">
                <h:outputText id="result" style="color:blue"
                              value="#{userNumberBean.response}"
                              rendered="#{!facesContext.validationFailed}"/>
                <h:message id="errors1"
                           showSummary="true"
                           showDetail="false"
                           style="color: #d20005;
                           font-family: 'New Century Schoolbook', serif;
                           font-style: oblique;
                           text-decoration: overline"
                           for="userNo"/>
            </h:panelGroup>
        </p>
    </h:form>
</h:body>

The most important change is in the h:commandButton tag. The action attribute is removed from the tag, and an f:ajax tag is added.

The f:ajax tag specifies that when the button is clicked the h:inputText component with the id value userNo is executed. The components within the outputGroup panel group are then rendered. If a validation error occurs, the managed bean is not executed, and the validation error message is displayed in the message pane. Otherwise, the result of the guess is rendered in the result component.

The UserNumberBean Backing Bean

A small change is also made in the UserNumberBean code so that the output component does not display any message for the default (null) value of the property response. Here is the modified bean code:

public String getResponse() {
    if ((userNumber != null)
            && (userNumber.compareTo(dukesNumberBean.getRandomInt()) == 0)) {
        return "Yay! You got it!";
    }
    if (userNumber == null) {
        return null;
    } else {
        return "Sorry, " + userNumber + " is incorrect.";
    }
}

The DukesNumberBean CDI Managed Bean

The DukesNumberBean session-scoped CDI managed bean stores the range of guessable numbers and the randomly chosen number from that range. It is injected into UserNumberBean with the CDI @Inject annotation so that the value of the random number can be compared to the number the user submitted:

@Inject
DukesNumberBean dukesNumberBean;

Running the ajaxguessnumber Example

You can use either NetBeans IDE or Maven to build, package, deploy, and run the ajaxguessnumber application.

To Build, Package, and Deploy the ajaxguessnumber Example Using NetBeans IDE

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. From the File menu, choose Open Project.

  3. In the Open Project dialog box, navigate to:

    jakartaee-examples/tutorial/web/faces
  4. Select the ajaxguessnumber folder.

  5. Click Open Project.

  6. In the Projects tab, right-click the ajaxguessnumber project and select Build.

    This command builds and deploys the project.

To Build, Package, and Deploy the ajaxguessnumber Example Using Maven

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. In a terminal window, go to:

    jakartaee-examples/tutorial/web/faces/ajaxguessnumber/
  3. Enter the following command:

    mvn install

    This command builds and packages the application into a WAR file, ajaxguessnumber.war, located in the target directory. It then deploys the application.

To Run the ajaxguessnumber Example

  1. In a web browser, enter the following URL:

    http://localhost:8080/ajaxguessnumber
  2. Enter a value in the field and click Submit.

    If the value is in the range of 0 to 10, a message states whether the guess is correct or incorrect. If the value is outside that range or if the value is not a number, an error message appears in red.

Further Information about Ajax in Jakarta Faces Technology

For more information on Ajax in Jakarta Faces Technology, see