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.
Name | Type | Description |
---|---|---|
|
|
A |
|
|
A |
|
|
A |
|
|
A |
|
|
The name of the listener method that is called when a |
|
|
The name of the JavaScript function that handles UI events. |
|
|
The name of the JavaScript function that handles errors. |
|
|
A |
The keywords listed in Execute and Render Keywords can be used with the execute
and render
attributes of the f:ajax
tag.
Keyword | Description |
---|---|
|
All component identifiers |
|
The form that encloses the component |
|
No component identifiers |
|
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.
Property | Description |
---|---|
|
The response to the Ajax call in XML format |
|
The response to the Ajax call in text format |
|
The response to the Ajax call in numeric code |
|
The source of the current Ajax event: the DOM element |
|
The status of the current Ajax call: |
|
The type of the Ajax call: |
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.
Values | Description |
---|---|
|
No Ajax response from server. |
|
One of the valid HTTP errors: |
|
The Ajax response is not well formed. |
|
The Ajax response contains an |
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 – Uses the
h:outputScript
tag directly in a Facelets page -
Using the @ResourceDependency Annotation in a Bean Class – Uses the
jakarta.faces.application.ResourceDependency
annotation on aUIComponent
Java class
Using JavaScript API in a Facelets Application
To use the JavaScript resource API directly in a web application, such as a Facelets page:
-
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 thehead
element on the HTML page. -
Identify the component to which you would like to attach the Ajax functionality.
-
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, typicallythis
. 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 therender
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:
-
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;
You will learn more about CDI in Introduction to Jakarta Contexts and Dependency Injection.
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
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
jakartaee-examples/tutorial/web/faces
-
Select the
ajaxguessnumber
folder. -
Click Open Project.
-
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
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
jakartaee-examples/tutorial/web/faces/ajaxguessnumber/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
ajaxguessnumber.war
, located in thetarget
directory. It then deploys the application.
To Run the ajaxguessnumber Example
-
In a web browser, enter the following URL:
http://localhost:8080/ajaxguessnumber
-
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
-
Jakarta Faces project website:
https://jakarta.ee/specifications/faces/3.0/