0

I have a simple form which should call the method countryChanged() in my Login-Bean.

<h:form id="languageForm">
    <p:selectOneMenu value="#{login.locale}" var="locale" effect="fold">
        <p:ajax listener="#{login.countryChanged}" />
        <f:selectItem itemLabel="#{gui.LANGUAGE}" itemValue=""></f:selectItem>  
        <f:selectItems value="#{login.locales}" var="locales" itemLabel="#{locales.displayLanguage}" itemValue="#{locales}" />                  
         <p:column><h:graphicImage library="images" name="flags/#{locale.country}.png" /></p:column>
         <p:column>#{locale.displayName}</p:column>
    </p:selectOneMenu>
</h:form>


<h:form id="loginForm">
<h:panelGrid columns="2" title="Flexicon Login">
    <h:outputLabel for="login">#{gui.LOGIN}</h:outputLabel>
    <h:inputText id="login" required="true" value="#{loginControl.login}" label=""></h:inputText>
    <h:outputLabel for="password">#{gui.PASSWORD}</h:outputLabel>
    <h:inputSecret id="password" value="#{loginControl.password}"></h:inputSecret>
</h:panelGrid>
<p:messages></p:messages>
<h:commandButton value="#{gui.BTN_LOGIN}" action="#{loginControl.login}"></h:commandButton>
</h:form>

Login-Bean

@ManagedBean(name="login")
@SessionScoped
public class LoginControl implements Serializable {
private static final long serialVersionUID = 5887191233181008116L;
private String login;
private String password;
private Locale locale;
private List<Locale> locales; 

public LoginControl(){

}

public String getLogin() {
    return login;
}

public void setLogin(String login) {
    this.login = login;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public Locale getLocale() {
    if(locale==null){
        locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    }
    return locale;
}

public void setLocale(Locale locale) {
    //FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    this.locale = locale;
}

public List<Locale> getLocales() {
    if(locales==null){
        Logger.getLogger(LoginControl.class).info("initializing locales...");
        locales = new ArrayList<Locale>();
        locales.add(Locale.GERMANY);
        locales.add(Locale.UK);
        locales.add(Locale.FRANCE);
    }
    return locales;
}

public void setLocales(List<Locale> locales) {
    this.locales = locales;
}

public void countryChanged(){
    FacesContext.getCurrentInstance().getViewRoot().setLocale(getLocale());
}   
}

I followed the several advices which are already discussed here in stackoverflow. But somehow it doesn't want to work. Can anybody see a mistake?

2 Answers2

0

You've a conversion error. If you have paid attention to the server log, you'd have noticed a warning about an enqueued but undisplayed faces message. You should have used <p:messages autoUpdate="true"/> instead to auto-update it during submits so that any conversion/validation error messages will properly show up in the UI.

Your concrete problem is caused because you're attempting to set a non-standard Java object type java.util.Locale as item value. JSF/EL doesn't have builtin converters/coercions for this like as it has for String, Number and Boolean.

You've 2 options to fix this problem:

  1. Use String instead of Locale as item value and reconstruct Locale around the submitted string in the listener method.

    <p:selectOneMenu value="#{login.language}" ...>
        <f:selectItems itemValue="#{locales.language}" />                  
        ...
    </p:selectOneMenu>
    

    with

    private String language;
    
    public void countryChanged() {
        Locale locale = new Locale(language);
        // ...
    }
    

  2. Create custom converter which converts between Locale (in the model) and String (in the HTML).

    @FacesConverter(forClass=Locale.class)
    public class LocaleConverter implements Converter {
        // Implement accordingly.
    }
    
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
-1

You're missing the client side event to trigger the ajax request.

Try this: event="change"

<h:form>
   <p:selectOneMenu>
       <p:ajax event="change" listener="#{bean.action}" />
       <f:selectItem itemLabel="foo" itemValue="0"/>
       <f:selectItem itemLabel="bar" itemValue="1"/>
   </p:selectOneMenu>
</h:form>
Jörg
  • 7
  • 1
    Wrong. The default event is `valueChange` which is already the right one. Whoever upvoted this answer has to reconsider his incorrect upvote. – BalusC Oct 18 '12 at 19:20