I am trying to use a javax.faces.event.ValueChangeListener
against a h:selectOneMenu
like so
<h:selectOneMenu value="#{localeBean.languageCode}" onchange="submit()">
<f:selectItem itemLabel="English" itemValue="en" />
<f:selectItem itemLabel="German" itemValue="de" />
<f:valueChangeListener type="org.bitbucket.paulstat.jsf.event.ExampleValueChangeListener" />
</h:selectOneMenu>
This is the listener
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
import javax.inject.Inject;
import org.bitbucket.paulstat.jsf.localisation.LocaleBean;
public class ExampleValueChangeListener implements ValueChangeListener {
@Inject
private LocaleBean localeBean;
@Override
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
localeBean.setLanguageCode(event.getNewValue().toString());
localeBean.switchLocale();
}
}
And the LocaleBean
import java.io.Serializable;
import java.util.Locale;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
@Named
@SessionScoped
public class LocaleBean implements Serializable {
private String languageCode;
public void switchLocale() {
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(languageCode));
}
public void setLanguageCode(String languageCode) {
this.languageCode = languageCode;
}
public String getLanguageCode() {
return languageCode;
}
}
The LocaleBean
doesn't appear to be being injected in the value change listener and is null. Can we mix SessionScoped CDI beans with JSF ValueChangeListeners?
@Inject
works only in CDI managed beans. Your ExampleValueChangeListener
isn't a CDI managed bean.
Make it one. Easiest way is to put the @Named
annotation on it so it's available in EL.
@Named
public class ExampleValueChangeListener implements ValueChangeListener {
// ...
}
Reference it via binding
instead of type
.
<f:valueChangeListener binding="#{exampleValueChangeListener}" />