JSF 2 has Ajax built in, lets take a look at how it works.
the tag (all attributes optional): <f:ajax event="keyup" render="ID to update, or EL" listener="#{bean.method}"/>
use case: user input a message, an output field renders the message vi ajax call to server side backing bean.
screenshot:
the page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test JSF Ajax</title>
</h:head>
<h:body>
<h:form>
<p:panel header="message input" toggleable="true" style="width:50%">
ur message to backing bean: <p:inputText id="input" value="#{jsfAjaxTest.message}"/>
<h:commandButton name="cmdBtn" value="Go" action="#{jsfAjaxTest.go}">
<f:ajax execute="input" render="output"/>
</h:commandButton>
</p:panel>
<p:panel header="ur message ajax-rendered" style="width:50%">
<h:outputText id="output" value="#{jsfAjaxTest.hi}"/>
</p:panel>
</h:form>
</h:body>
</html>
the backing bean
package com.jxee.action.jsfajax;
import javax.faces.bean.ManagedBean;
@ManagedBean
public class JsfAjaxTest {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getHi() {
return (message != null ? message : "nothing");
}
/**
* jsf ajax enabled action method.
* although it could be "public void go()", returning a String would
* satisfy a normal action handler and ajax method call as well.
*/
public String go() {
return null; // null would cause form re-displayed
}
}
next, we add a dropdown list input component and use execute="@form" to submit all the fields in the http form for server processing:
screenshot 2:
source code of the updated page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test JSF Ajax</title>
</h:head>
<h:body>
<h:form>
<p:panel header="message input" toggleable="true" style="width:50%">
ur message to backing bean:
<p:inputText id="msgInput" value="#{jsfAjaxTest.message}"/>
<br/>
select ur preferred language:
<p:selectOneMenu id="idSelectLang" value="#{jsfAjaxTest.lang}">
<f:selectItems value="#{jsfAjaxTest.languages}"/>
<f:ajax execute="@form" render="output1 output2"/>
</p:selectOneMenu>
</p:panel>
<p:panel header="ajax-rendered" style="width:50%">
<h:outputText id="output1" value="#{jsfAjaxTest.hi}"/>
<br/>
<h:outputText id="output2" value="#{jsfAjaxTest.lang}"/>
</p:panel>
</h:form>
</h:body>
</html>
updated source code of the supporting bean:
package com.jxee.action.jsfajax;
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
@ManagedBean
public class JsfAjaxTest {
private String message;
private String lang;
private SelectItem[] languages;
public JsfAjaxTest() {
languages = new SelectItem[] {
new SelectItem("unknown", "-select one-"),
new SelectItem("C", "-C"),
new SelectItem("Java", "-Java"),
new SelectItem("PHP", "-PHP"),
new SelectItem("Ruby", "-Ruby")
};
}
public SelectItem[] getLanguages() {
return languages;
}
public void setLanguages(SelectItem[] languages) {
this.languages = languages;
}
public String getLang() {
return (lang != null ? "ur favorite language: " + lang : "");
}
public void setLang(String lang) {
this.lang = lang;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getHi() {
return (message != null ? "ur input msg: " + message : "");
}
/**
* jsf ajax enabled action method.
* although it could be "public void go()", returning a String would
* satisfy a normal action handler and ajax method call as well.
*/
public String go() {
return null; // null would cause form re-displayed
}
}
Next, add a listener to the ajax event
Add the listener method in the backing bean:
/**
* an jsf ajax listener
*/
public void myAjaxListener(AjaxBehaviorEvent event) {
log.debug("hi, im ur JSF ajax listener and working hard... ");
}
Add the listener attribute to the tag:
1. event="keyup": the text would be rendered on the output panel as you type, and
2. u'll get lots of debug lines in your server log
<f:ajax event="keyup" render="output1" listener="#{jsfAjaxTest.myAjaxListener}"/>
小姐一下:
1. JSF2 has ajax functionality built-in.
2. Simple usage: <f:ajax execute="id0 id1 ..." render="id10 id12 ..."/>
3. In the simple usage, "execute" defines the elements(thus its value) to pass to server for process, and "render" defines the elements to update after server process completes. Multiple DOM IDs can use space as delimiter.
4. Note though that the elements to be ajax updated must be in the same "form" as the <f:ajax/>
5. JSF built-in Ajax can catch other events, like "keyup", "blur" etc, with the "event" attribute. this is not explored in this example.
6. If you want to submit all the fields in the "form" to server, then the "execute" attribute can set like execute="@form".
7. Primefaces Ajax functionalities are said to be based on JSF's built-in Ajax function.