如果使用者改變了JSF輸入元件的值後送出表單,就會發生值變事件(Value Change Event),這會丟出一個javax.faces.event.ValueChangeEvent物件,如果您想要處理這個事件,有兩種方式,一是直接 設定JSF輸入元件的valueChangeListener屬性,例如:
<h:selectOneMenu value="#{user.locale}"
onchange="this.form.submit();"
valueChangeListener="#{user.changeLocale}">
<f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
onchange="this.form.submit();"
valueChangeListener="#{user.changeLocale}">
<f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
為了模擬GUI中選擇了選單項目之後就立即發生反應,我們在onchange屬性中使用了JavaScript,其作用是在選項項目發生改變之後,立即送 出表單,而不用按下提交按鈕;而valueChangeListener屬性所綁定的user.changeLocale方法必須接受 ValueChangeEvent物件,例如:
- UserBean.java
package onlyfun.caterpillar;
import javax.faces.event.ValueChangeEvent;
public class UserBean {
private String locale = "en";
private String name;
private String password;
private String errMessage;
public void changeLocale(ValueChangeEvent event) {
if(locale.equals("en"))
locale = "zh_TW";
else
locale = "en";
}
public void setLocale(String locale) {
this.locale = locale;
}
public String getLocale() {
if (locale == null) {
locale = "en";
}
return locale;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public void setErrMessage(String errMessage) {
this.errMessage = errMessage;
}
public String getErrMessage() {
return errMessage;
}
public String verify() {
if(!name.equals("justin") ||
!password.equals("123456")) {
errMessage = "名稱或密碼錯誤";
return "failure";
}
else {
return "success";
}
}
}
另一個方法是實作javax.faces.event.ValueChangeListener介面,並定義其processValueChange() 方法,例如:
package onlyfun.caterpillar;
....
public class SomeListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) {
....
}
....
}
....
public class SomeListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) {
....
}
....
}
然後在JSF頁面上使用<f:valueChangeListener>標籤,並設定其type屬性,例如:
<h:selectOneMenu value="#{user.locale}"
onchange="this.form.submit();">
<f:valueChangeListener
type="onlyfun.caterpillar.SomeListener"/>
<f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
onchange="this.form.submit();">
<f:valueChangeListener
type="onlyfun.caterpillar.SomeListener"/>
<f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
<f:selectItem itemValue="en" itemLabel="English"/>
</h:selectOneMenu>
下面這個頁面是對 立即事件 中的範例程式作一個修改,將語言選項改以下拉式選單的選擇方式呈現,這必須配合上面提供的UserBean類別來使用:
- index.jsp
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@page contentType="text/html;charset=UTF8"%>
<f:view locale="#{user.locale}">
<f:loadBundle basename="messages" var="msgs"/>
<html>
<head>
<title><h:outputText value="#{msgs.titleText}"/></title>
</head>
<body>
<h:form>
<h:selectOneMenu value="#{user.locale}"
immediate="true"
onchange="this.form.submit();"
valueChangeListener="#{user.changeLocale}">
<f:selectItem itemValue="zh_TW"
itemLabel="Chinese"/>
<f:selectItem itemValue="en"
itemLabel="English"/>
</h:selectOneMenu>
<h3><h:outputText value="#{msgs.hintText}"/></h3>
<h:outputText value="#{msgs.nameText}"/>:
<h:inputText value="#{user.name}"/><p>
<h:outputText value="#{msgs.passText}"/>:
<h:inputSecret value="#{user.password}"/><p>
<h:commandButton value="#{msgs.commandText}"
action="#{user.verify}"/>
</h:form>
</body>
</html>
</f:view>