Ajax Framework

Introduction

OpenFaces library has a range of Ajax-powered features built-in into components themselves, and various means for introducing generic inter-component Ajax-based interactions. The generic Ajax support is provided by the appropriate attributes in the OpenFaces command components, such as <o:commandButton>, <o:commandLink>, <o:menuItem>, and <o:captionButton>. In addition to this, there's a generic mechanism provided by the Ajax component. This is a non-visual component that can be attached to any other JSF component to reload other components when some particular event occurs. Actually the Ajax component has a wider purpose than just reloading components which makes it possible to perform dynamic page updates to meet a wide range of scenarios that require Ajax page updates. Please see the Ajax component documentation page for the detailed information on its capabilities and usage instructions.

The OpenFaces components that have built-in Ajax features are configured to use Ajax by default. This is acceptable for the majority of cases, though it is sometimes needed to disable Ajax support for a particular component. This can be done on a per-component basis. Please refer to a documentation on respective components for instructions on disabling Ajax. When Ajax support is turned off, the page is submitted whenever data update is needed, instead of making an Ajax request.

OpenFaces also provides an ability to customize various aspects of Ajax processing such as Ajax progress message, the way of handling session expiration during Ajax requests, and receiving notifications of Ajax related events. The way of handling session expiration and customizing progress message can be configured for the whole application by using the application-scope parameters in web.xml file or on a page-wide level using the AjaxSettings component.

Note
Resources from the <f:loadBundle> tag cannot be used inside Ajax-enabled components. Use <o:loadBundle> tag instead. See the LoadBundle documentation.

The AjaxRequest Class

As described in the subsections below, the AjaxRequest class gives a programmatic control over some aspects of Ajax requests. An instance of the AjaxRequest class corresponding to the current Ajax request can be received using the static AjaxRequest.getInstance() function. This function returns null if the current request is not an OpenFaces Ajax request.

Loading Data with Ajax

Besides executing server actions and reloading components, the OpenFaces Ajax framework allows passing the application-specific data along with any Ajax request. The value that is returned to the client side along with the Ajax request is called the ajaxResult value. ,The application action handlers can use one of the following three approaches for specifying the ajaxResult value:

  • It is possible to specify the ajaxResult property of the current AjaxRequest instance explicitly.
  • When using the actionListener (or listener) attribute for declaring action handlers, it is possible to declare the Ajax action listener method with the AjaxActionEvent parameter (instead of the usual ActinEvent type which is also allowed when declaring Ajax action listener method), and specify the required value by invoking its setAjaxResult method.

The ajaxResult value, can have one of the following types:

  • any primitive type wrapper (java.lang.Integer, java.lang.Boolean, etc...);
  • java.lang.String;
  • a collection or an array of any of the types listed here;
  • a map with string keys and values of any of the types listed here.

The ajaxResult value will be available in the ajaxResult property of the onajaxend event for the corresponding Ajax request. The primitive and string types will be represented with their JavaScript analogs, collections and arrays will be represented as JavaScript arrays, and maps will be represented with JavaScript objects, where each key/value pair will be represented with an appropriate object's field.

Specifying Additional Components for Reloading During Ajax Request

The list of components that should be reloaded during the Ajax request is usually specified with the render attriute of a component which triggers the Ajax request (e.g. in the <o:ajax>, or <o:commandButton> tag). Nevertheless it is also possible to add more reloaded components programmatically during the Ajax request itself. To do this, the Ajax event processing code should use one of the addReloadedComponent functions of the AjaxRequest class. This function receives either client Id of the reloaded component or the UIComponent reference.

Application-Wide Configuration

You can configure the way of handling session expiration during Ajax request and configure Ajax progress message for the whole application by specifying the application-scope context parameters in web.xml file. These parameters can be overridden by the AjaxSettings component for the separate page.

Session Expiration Settings

To specify the way of how session expiration during Ajax request is handled you should use the org.openfaces.ajax.sessionExpiration application-scope context parameter in web.xml file. This property has two possible values:

  • "default" (default). The confirmation that asks the user to reload the page appears when the current session is expired.
  • "silent". The page is reloaded when the current session is expired.

In order for the session expiration feature to work properly with MyFaces 1.2, add the following lines to the WEB-INF/web.xml file:

<context-param>
    <param-name>org.apache.myfaces.ERROR_HANDLING</param-name>
    <param-value>false</param-value>
</context-param>

Ajax Progress Message Settings

When any Ajax request is in progress, the "Loading..." message appears in the upper-right corner of the screen. This message is displayed by default. You can configure this message for the whole application or for the particular page.

You can change the Ajax progress message for the whole application by specifying the org.openfaces.ajaxMessageHTML parameter in web.xml. This parameter should be specified as portion of HTML that will be shown in the upper-right corner on an Ajax request.

For example you can add the following code to web.xml:

<context-param>
  <param-name>org.openfaces.ajaxMessageHTML</param-name>
  <param-value><![CDATA[
    <div style="background: white;
                font: Tahoma 15pt normal;
                border: 1px solid black;">
      <img src="/testapp/images/progress.gif"/>
      Ajax request is currently in progress!
    </div>
  ]]></param-value>
</context-param>

Page-Wide Configuration

Configuration of all Ajax-related settings for the particular page can be done by placing the AjaxSettings component on the page. To add the AjaxSettings component to a page, use the <o:ajaxSetting> tag. There should be only one <o:ajaxSetting> tag on the page.

The AjaxSettings component overrides the application-scope context parameters for the particular page. You can specify two facets for the <o:ajaxSettings> tag:

The <o:ajaxSettings> tag also has attributes to configure Ajax-related events. For more information please see the Ajax Request Lifecycle Events section.

Session Expiration Settings

The way how session expiration during Ajax requests is handled can be configured using the "sessionExpiration" facet of the <o:ajaxSetting> tag. You can define use of the following tags in the "sessionExpiration" facet:

  • <o:defaultSessionExpiration>. An attempt to perform an Ajax action on an expired session shows the confirmation dialog that asks the user either to reload the page with a new session. The confirmation itself can be customized by placing the <o:confirmation> tag into the "confirmation" facet of <o:defaultSessionExpiration> tag and specifying its appearance attributes appropriately.
  • <o:silentSessionExpiration>. The page is reloaded without a notice when an Ajax request on an expired session is made.

The following example demonstrates the usage of the "sessionExpiration" facet. The page with this AjaxSettings tag is reloaded when the session is expired.

<o:ajaxSettings>
  <f:facet name="sessionExpiration">
    <o:silentSessionExpiration/>
  </f:facet>
</o:ajaxSettings>

You can also specify a JavaScript code that should be executed when the current session is expired. For more details please see the Ajax Request Lifecycle Events section.

Please note that if the onsessionexpired event is specified together with "sessionExpiration" facet, first the JavaScript code specified in the onsessionexpired event is executed and then goes the logic specified by the "sessionExpiration" facet. However, if the JavaScript code specified for the onsessionexpired event returns false, the logic of DefaultSessionExpiration or SilentSessionExpiration components is not executed at all allowing the custom application code to handle session expiration in an application-specific way.

Ajax Progress Message Settings

You can customize the Ajax progress message for a separate page by using the <o:defaultProgressMessage> tag. This tag should be declared in the "progressMessage" facet of the <o:ajaxSettings> tag.

This tag lets you can customize a text and an image, and a style for the progress message. The text can be customized using the text attribute of the <o:defaultProgressMessage> tag. The URL to the image file that is displayed besides the text can be specified using the imageUrl attribute. To apply styles for the progress message, use the style and styleClass attributes.
The progress message can be shown as semi-transparent using the transparency attribute that accepts a double value between 0 and 1. The default value is 0, which corresponds to the fully opaque display. It is also possible to make the transparency gradually gain its full strength in a specified number of milliseconds using the transparencyTransitionPeriod attribute, which is equal to 0 by default, which means that a message appears instantaneously.

You can customize the position of the Ajax progress message using the horizontalAlignment (accepts "left", "center", and "right" values), and the verticalAlignment (accepts "top", "center", and "bottom" values).

It is possible to shade contents of the browser window while Ajax request is in progress to prevent mouse operations with the document until the request finishes. This can be done by setting the fillBackground attribute to true. Style, transparency level and transparency transition period for the background layer of Ajax progress message can be customized with the backgroundStyle/backgroundClass, backgroundTransparency, and backgroundTransparencyTransitionPeriod attributes respectively.

Here is an example of using the DefaultProgressMessage component:

<o:ajaxSettings>
  <f:facet name="progressMessage">
    <o:defaultProgressMessage imageUrl="ajaxImage.png" text="Custom loading message"
                              style="color: green; border: 2px solid green;"/>
  </f:facet>
</o:ajaxSettings>

Handling Ajax Errors

When any error occurs while Ajax request is performed, a JavaScript alert message with information about the error appears by default. You can change this behavior by specifying the onerror attribute of the AjaxSettings component. This attribute specifies JavaScript code that should be executed when an error occurs while performing an Ajax request. If the JavaScript code specified on the onerror attribute returns false, the default error message alert is not displayed.

Ajax Request Lifecycle Events

You can specify Ajax-related client-side events using the following attributes of the <o:ajaxSettings> tag:

Attribute Description
onajaxstart JavaScript code that should be executed when an Ajax request is started.
onajaxend JavaScript code that should be executed when an Ajax request is completed.
onerror JavaScript code that should be executed when an error occurs while performing an Ajax request.
onsessionexpired JavaScript code that should be executed when an Ajax request is being made on an expired session.

Limitations

Please be aware of the following limitations when using the Ajax-enabled components:

  • Dynamic variables (such as xhtml template parameters or iterator/DataTable variable) cannot be used when declaring the action attribute, which is invoked with Ajax. You can work around this by using invoking the appropriate Ajax request with the JavaScript Ajax API, and passing the appropriate parameters using the params option like this: O$.ajax.request(this, event, {render: "form:component", listener: "MyBean.actionListener", params: {param1: "#{var1}", param2: "#{var2}"} });
  • You cannot reload a form with Ajax directly. To address this, just wrap form's content in any container tag, e.g. <h:panelGroup>, and reload that container by its id instead.
OpenFaces