When user make changes in input components, such as h:inputText or h:selectOneMenu, the JSF “value change event” will be fired.

Two ways to implement it :

1. Method binding – In input component, specified a bean’s method directly in the “valueChangeListener” attribute.
JSF…

<h:selectOneMenu value="#{bean.value}" onchange="submit()"
	valueChangeListener="#{bean.valueChangeMethod}">
   	<f:selectItems value="#{bean.values}" />
</h:selectOneMenu>

Java…
The method which interact with value change event should accept a ValueChangeEvent parameter.

@ManagedBean(name="bean")
@SessionScoped
public class BeanBean{
 
	public void valueChangeMethod(ValueChangeEvent e){
		//...
	}
 
}

2. ValueChangeListener interface – In input component, add a “f:valueChangeListener” tag inside, and specified an implementation class of ValueChangeListener interface.
JSF…

<h:selectOneMenu value="#{bean.value}" onchange="submit()">
    <f:valueChangeListener type="ValueListenerXXX" />
   	<f:selectItems value="#{bean.values}" />
</h:selectOneMenu>

Java…
Implements ValueChangeListener interface and override the processValueChange() method.

public class ValueListenerXXX implements ValueChangeListener{
 
	@Override
	public void processValueChange(ValueChangeEvent event)
			throws AbortProcessingException {
 
		//...
 
	}
}
Note
To make it work, you have to attach a onchange=”submit()” JavaScript to the input component; Otherwise, no event will be fired.

Full valueChangeListener example

Here’s a JSF 2.0 application, with a dropdownbox (h:selectOneMenu) and a textbox (h:inputText), when user make changes in the dropdown box, it will fire the “value change event” and update the textbox with newly selected dropdown box value.

This example is demonstrate in both “Method binding” and “ValueChangeListener” way.

1. Method binding

A country bean to provide a list of the countries and locale code for demonstration. You can bind the bean’s method via “valueChangeListener” attribute in input component. See below :

CountryBean.java

package com.mkyong;
 
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
 
@ManagedBean(name="country")
@SessionScoped
public class CountryBean implements Serializable{
 
	private static final long serialVersionUID = 1L;
 
	private static Map<String,String> countries;
 
	private String localeCode = "en"; //default value 
 
	static{
		countries = new LinkedHashMap<String,String>();
		countries.put("United Kingdom", "en"); //label, value
		countries.put("French", "fr");
		countries.put("German", "de");
		countries.put("China", "zh_CN");
	}
 
	public void countryLocaleCodeChanged(ValueChangeEvent e){
		//assign new value to localeCode
		localeCode = e.getNewValue().toString();
 
	}
 
	public Map<String,String> getCountryInMap() {
		return this.countries;
	}
 
	public String getLocaleCode() {
		return localeCode;
	}
 
	public void setLocaleCode(String localeCode) {
		this.localeCode = localeCode;
	}
 
}

JSF page

<?xml version="1.0" encoding="UTF-8"?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      >
    <h:body>
 
    	<h1>JSF 2 valueChangeListener example</h1>
 
	  <h:form>
 
	  <h:panelGrid columns="2">
 
		Selected country : 
		<h:inputText id="country" value="#{country.localeCode}" size="20" />
 
		Select a country {method binding}: 
		<h:selectOneMenu value="#{country.localeCode}" onchange="submit()"
			valueChangeListener="#{country.countryLocaleCodeChanged}">
   			<f:selectItems value="#{country.countryInMap}" />
   		</h:selectOneMenu>
 
	  </h:panelGrid>
 
	</h:form>
 
    </h:body>
</html>

2. ValueChangeListener interface

Reuse above country bean to provide a list of the countries and locale code. Implements the ValueChangeListener interface and bind it via “f:valueChangeListener” tag. See below :

CountryValueListener.java

package com.mkyong;
 
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
 
public class CountryValueListener implements ValueChangeListener{
 
	@Override
	public void processValueChange(ValueChangeEvent event)
			throws AbortProcessingException {
 
		//access country bean directly
		CountryBean country = (CountryBean) FacesContext.getCurrentInstance().
			getExternalContext().getSessionMap().get("country");
 
		country.setLocaleCode(event.getNewValue().toString());
 
	}
 
}

JSF page

<?xml version="1.0" encoding="UTF-8"?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      >
    <h:body>
 
    	<h1>JSF 2 valueChangeListener example</h1>
 
	  <h:form>
 
	  <h:panelGrid columns="2">
 
		Selected country : 
		<h:inputText id="country" value="#{country.localeCode}" size="20" />
 
		Select a country {ValueChangeListener class}: 
		<h:selectOneMenu value="#{country.localeCode}" onchange="submit()">
			<f:valueChangeListener type="com.mkyong.CountryValueListener" />
   			<f:selectItems value="#{country.countryInMap}" />
   		</h:selectOneMenu>
 
	  </h:panelGrid>
 
	 </h:form>
 
    </h:body>
</html>

Demo

Default, country “United Kingdom” is selected.

jsf2-ValueChangeListener-example-1

If country dropdown box value is changed, fire valueChangeListener, and update the textbox value with newly selected dropdrow box value.

jsf2-ValueChangeListener-example-2

Download Source Code

Reference

  1. JSF 2 dropdown box example
Tags :
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider making a donation to this charity, thanks.

Related Posts

Popular Posts