JBoss.orgCommunity Documentation
This chapter details the basic components that respond to a user action and submit an Ajax request.
The <a4j:ajax>
behavior allows Ajax capability to be added to a non-Ajax component. The non-Ajax component must implement the ClientBehaviorHolder
interface for all the event attributes that support behavior rendering.
The <a4j:ajax>
behavior is placed as a direct child to the component that requires Ajax support.
Point the event
attribute to the standard JSF event that triggers the behavior. If the event
attribute is not defined, the behavior is triggered on the event that normally provides interaction behavior for the parent component.
Example 3.1. <a4j:ajax>
example
<h:panelGrid columns="2">
<h:inputText id="myinput" value="#{userBean.name}">
<a4j:ajax event="keyup" render="outtext" />
</h:inputText>
<h:outputText id="outtext" value="#{userBean.name}" />
</h:panelGrid>
client-behavior-renderer-type
: org.ajax4jsf.behavior.Ajax
behavior-id
: org.ajax4jsf.behavior.Ajax
handler-class
: org.richfaces.view.facelets.html.AjaxHandler
behavior-class
: org.ajax4jsf.component.behavior.AjaxBehavior
client-behavior-renderer-class
: org.ajax4jsf.renderkit.AjaxBehaviorRenderer
The <a4j:param>
behavior combines the functionality of the JavaServer Faces (JSF) components <f:param>
and <f:actionListener>
.
Basic usage of the <a4j:param>
requires three main attributes:
The value
attribute is the initial value of the parameter.
The assignTo
attribute defines the bean property. The property is updated if the parent command component performs an action event during the Process Request phase.
Example 3.2, “<a4j:param> example” shows a simple implementation along with the accompanying managed bean.
Example 3.2. <a4j:param>
example
<h:form id="form">
<a4j:commandButton value="Set name to Alex" reRender="rep">
<a4j:param name="username" value="Alex" assignTo="#{paramBean.name}"/>
</a4j:commandButton>
<h:outputText id="rep" value="Name: #{paramBean.name}"/>
</h:form>
public class ParamBean {
private String name = "John";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
When the name
parameter of the bean to Alex
, and displays the name in the output field.
The <a4j:param>
tag can be used with non-Ajax components in addition to Ajax components. This includes components which are working through the GET
request, such as the <h:link>
and <h:button>
components. In this way, data model values can also be updated without any Java code on the server side.
The converter
attribute can be used to specify how to convert the value before it is submitted to the data model. The property is assigned the new value during the Update Model phase.
If the validation of the form fails, the Update Model phase will be skipped and the property will not be updated.
Variables from JavaScript functions can be used for the value
attribute. In such an implementation, the noEscape
attribute should be set to true
. Using noEscape="true"
, the value
attribute can contain any JavaScript expression or JavaScript function invocation, and the result will be sent to the server as the value
attribute.
Example 3.3. Passing client-side parameters
<h:form>
<a4j:commandButton value="Show Screen Size" render="infoPanel">
<a4j:param name="w" value="screen.width"
assignTo="#{paramBean.screenWidth}" noEscape="true" />
<a4j:param name="h" value="screen.height"
assignTo="#{paramBean.screenHeight}" noEscape="true" />
</a4j:commandButton>
<h:panelGrid columns="2" id="infoPanel">
<h:outputText value="Width:" />
<h:outputText value="#{paramBean.screenWidth}" />
<h:outputText value="Height:" />
<h:outputText value="#{paramBean.screenHeight}" />
</h:panelGrid>
</h:form>
The command button triggers the <a4j:param>
behaviors and renders the output text. The <a4j:param>
behaviors pass client-side parameters for the screen width and height through the backing bean. These parameters are then used to populate the output text values.
Use the <a4j:actionListener>
tag to register an ActionListener
class on a parent action component. The class provided as a listener must implement the javax.faces.event.ActionListener
interface. Multiple listener methods can be registered on an action component in this way.
The <a4j:actionListener>
tag differs from the standard JSF tag by allowing a listener method to be defined instead of just a class. Use the listener
attribute to define the listener method.
The <a4j:commandButton>
component is similar to the JavaServer Faces (JSF) <h:commandButton>
component, but additionally includes Ajax support.
Button controls are typically used to perform complete form submissions for data storing. As a consequence, the <a4j:commandButton>
component has the execute="@form"
setting by default. To limit rendering to a different scope, redefine the execute
attribute.
The <a4j:commandButton>
requires only the value
attribute to function. Use the value
attribute to specify the text of the button.
By default, the <a4j:commandButton>
uses the click
event instead of the submit
event.
The <a4j:commandLink>
component is similar to the JavaServer Faces (JSF) <h:commandLink>
component, except that it includes plugged-in Ajax behavior.
Link controls are typically used to perform complete form submissions for data storing. As a consequence, the <a4j:commandLink>
component has the execute="@form"
setting by default. To limit rendering to a different scope, redefine the execute
attribute.
The <a4j:commandLink>
requires only the value
attribute to function. Use the value
attribute to specify the text of the link.
The <a4j:commandLink>
uses the click
event instead of the submit
event.
The <a4j:jsFunction>
component performs Ajax requests directly from JavaScript code and retrieves server-side data. The server-side data is returned in JavaScript Object Notation (JSON) format prior to the execution of any JavaScript code defined using the oncomplete
attribute.
The <a4j:jsFunction>
component requires the data
attribute. Use the data
attribute to define where the retrieved server-side data is stored.
Example 3.4, “<a4j:jsFunction> example” shows how an Ajax request can be initiated from the JavaScript and a partial page update performed. The JavaScript function can be invoked with the data returned by the Ajax response.
Example 3.4. <a4j:jsFunction>
example
<table width="400">
<tbody>
<tr>
<td>
<span onmouseover="updateName('Kate')"
onmouseout="updateName('')">Kate</span>
</td>
<td>
<span onmouseover="updateName('John')"
onmouseout="updateName('')">John</span>
</td>
<td>
<span onmouseover="updateName('Alex')"
onmouseout="updateName('')">Alex</span>
</td>
</tr>
<tr>
<td colspan="3">
Name: <b><h:outputText id="showname" value="#{functionBean.text}" /></b>
</td>
</tr>
</tbody>
</table>
<h:form>
<a4j:jsFunction name="updateName" render="showname">
<a4j:param name="name" assignTo="#{functionBean.text}"/>
</a4j:jsFunction>
</h:form>
The output text for the name is changed depending on which table cell the user hovers over with the mouse. The <a4j:jsFunction>
component manages the updating and display of the name.
The <a4j:jsFunction>
component allows the use of the <a4j:param>
component or the JavaServer Faces <f:param>
component to pass any number of parameters for the JavaScript function.
The <a4j:poll>
component allows periodical sending of Ajax requests to the server. It is used for repeatedly updating a page at specific time intervals.
The interval
attribute specifies the time in milliseconds between requests. The default for this value is 1000 ms (1 second).
The <a4j:poll>
component can be enabled and disabled using the enabled
attribute. Using Expression Language (EL), the enabled
attribute can point to a bean property to apply a particular attribute value.
The <a4j:push>
component performs real-time updates on the client side from events triggered at the server side. The events are pushed out to the client through the RichFaces messaging queue (which is bound to Java Messaging Service - JMS). When the <a4j:push>
component is triggered by a server event, it can in turn cause Ajax updates and changes.
The <a4j:push>
component uses the Comet model for pushing data to the client.
The <a4j:push>
uses Atmosphere framework on both client-side and server-side. In order to use Atmosphere on server-side, it is necessary to add Atmosphere libraries into project.
In Maven based project, you should add atmosphere-runtime
as runtime dependency (its version is managed by richfaces-bom
that your project should be importing):
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
</dependency>
It is possible to trigger push events on server-side in several ways:
JMS - RichFaces Push consumes messages from enterprise messaging system and exposes them to client (tightly coupled with JMS runtime)
TopicsContext - accesses RichFaces message queue directly
Push CDI - uses the CDI Event mechanism to access TopicsContext
On the client side, push notifications may be processed in the following ways:
ondataavailable
event attribute - <a4j:push>
(serialized message is available through event.rf.data
)
Attaching a behavior to the dataavailable
event - any behavior may be attached (<a4j:ajax>
, <rich:componentControl>
, etc.)
No matter which method of producing messages is chosen, the message is delivered to the client based on the topic name (with optional subtopic).
Examples of topic names might be someTopic
or subtopic@anotherTopic
.
A push notification sent from the server to the <a4j:push>
component on the client will cause it to trigger any event handlers defined using the dataavailable
event handler.
The <a4j:push>
component should also include the onerror
event handler to inform the user when an error has occurred with the push notifications.
The topic name may be determined dynamically at runtime, using Expression Language expressions.
Example 3.5. Handling a push notification
<a4j:push address="#{chatBean.messagesSubtopic}@chat"
onerror="alert(event.rf.data)"
ondataavailable="jQuery('<div/>').
prependTo('.#{chatBean.channelName}Output').text(
getMessageString(event.rf.data))" />
This example uses the dataavailable
event attribute with some JavaScript to update messages in a chat room. The event.rf.data
parameter contains JMS message data serialized to JavaScript.
<a4j:push>
can be used for either immediate processing of messages (like in the previous example) or it can trigger partial page update (see the following example).
Example 3.6. Updating DOM for each push notification
<a4j:push address="chat"
onerror="alert(event.rf.data)">
<a4j:ajax event="datavailable" render="chat" />
</a4j:push>
This example uses the dataavailable
event handler to trigger an AJAX request and partial page update.
The JMS instance on the back-end must be configured to work with your <a4j:push>
components. Refer to the JBoss Application Server Administration Console Guide for details on managing JBoss Application Server through the Administration Console.
Example 3.7. JMS server configuration
This example describes the JMS server configuration required for a simple chat room. The chat room requires topics on the JMS server for the push functionality to check for new messages. Create a new JMS topic using the following settings:
Name: chat
JNDI name: /topic/chat
Use the default settings for other options.
Add a single role for the topic in the same form using the following settings:
Name: guest
Send: true
Consume: true
Create subscriber: true
Delete subscriber: true
Create durable subscriber: true
Delete durable subscriber: true
Ensure the Create durable subscriber and Delete durable subscriber options are set to true for push functionality. Durable subscriptions receive all events, including those events which were sent while the push component was not connected.
Refer to JMS Documentation for details on configuring the JMS Server.
With the JMS server configured, use the <a4j:push>
component's address
attribute to reference the topic on the JMS server that contains the pushed messages.
Example 3.8. Basic usage
<a4j:push id="pushJms" address="pushJms"
ondataavailable="jQuery(#{rich:element('serverDate')}).text(event.rf.data)" />
<a4j:outputPanel id="serverDate" layout="block">
<i>waiting for event...</i>
</a4j:outputPanel>
TopicSession session;
TopicPublisher publisher;
public void sendCurrentDate() throws JMSException {
String currentDate = new Date().toString();
ObjectMessage message = session.createObjectMessage(message);
publisher.publish(message);
}
This example demonstrates a simple use of the <a4j:push>
causing immediate update of page content.
Since JMS coupling may be unwanted in certain cases, RichFaces provides a switch to turn off the JMS integration:
<context-param>
<param-name>org.richfaces.push.jms.disable</param-name>
<param-value>true</param-value>
</context-param>
This switch is necessary when you want to make use of the alternative methods for sending push notifications: Push CDI or the TopicsContext
programmatic interface.
Alternative way of producing messages is using the TopicsContext
interface directly as in the following sample:
private TopicKey topicKey = new TopicKey("topicName");
public void initializeTopic() {
TopicsContext topicsContext = TopicsContext.lookup();
topicsContext.getOrCreateTopic(topicKey);
}
public void sendMessage(String message) throws MessageException {
TopicsContext topicsContext = TopicsContext.lookup();
topicsContext.publish(topicKey, message);
}
Sending a message using the TopicsContext
involves creating a TopicKey
instance (denominator of given message topic) and looking up the TopicsContext
used for topic registration and message publishing.
Using the TopicsContext
requires the FacesContext
instance to be available in the current thread.
The method TopicsContext.lookup()
can be called only in the context of a web application class loader (ServiceTracker
needs to be accessible for given application).
A second alternative way of producing messages is to use the CDI Event mechanism.
Push notifications can be produced by annotating a CDI event injection point with the @Push
annotation, which specifies an end-point (topic name).
The payload of the message is the serialized object sent using the CDI event interface (Event.fire(T object)
).
@Inject
@Push(topic = "someTopic")
Event<String> pushEvent;
public void sendMessage(String message) {
pushEvent.fire(message);
}
TopicsContext
interface.
Event.select(Annotation...)
and the @Push
CDI qualifier.