15

One of the most common approaches to change locale in JSF+Seam - with <h:selectOneMenu>:

<h:form  action="#{localeSelector.select}" rendered="false">
    <h:selectOneMenu value="#{localeSelector.language}" onchange="submit()">
        <f:selectItem itemLabel="English" itemValue="en" />
        <f:selectItem itemLabel="Francais" itemValue="fr" />
    </h:selectOneMenu>
</h:form>

I want to implement locale changes with buttons. So, the question is - how to pass the parameter (en, fr, etc.) to update the bean with <h:commandButton>? Maybe <h:inputHidden> would help?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Serga
  • 253
  • 1
  • 4
  • 10
  • Why do you want to send the value? When the form is submitted, the method setLanguage() on your Bean localeSelector will be automatically called. – santedicola Oct 24 '12 at 12:15
  • Your `` is by the way strange. This is not valid JSF. Did you write this from top of head or something instead of copypasting? @Sante: OP is concretely asking how to do the same with only a bunch of buttons (thus, *without* the dropdown list). – BalusC Oct 24 '12 at 12:34

1 Answers1

31

Either pass as method argument (only if your environment supports EL 2.2),

<h:commandButton value="English" action="#{localeSelector.change('en')}" />
<h:commandButton value="Deutsch" action="#{localeSelector.change('de')}" />
<h:commandButton value="Français" action="#{localeSelector.change('fr')}" />

with

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

Or use <f:setPropertyActionListener>

<h:commandButton value="English" action="#{localeSelector.change}">
    <f:setPropertyActionListener target="#{localeSelector.language}" value="en" />
</h:commandButton>
<h:commandButton value="Deutsch" action="#{localeSelector.change}">
    <f:setPropertyActionListener target="#{localeSelector.language}" value="de" />
</h:commandButton>
<h:commandButton value="Français" action="#{localeSelector.change}">
    <f:setPropertyActionListener target="#{localeSelector.language}" value="fr" />
</h:commandButton>

with

private String language;

public void change() {
    locale = new Locale(language);
    // ...
}

Or use <f:param>

<h:commandButton value="English" action="#{localeSelector.change}">
    <f:param name="language" value="en" />
</h:commandButton>
<h:commandButton value="Deutsch" action="#{localeSelector.change}">
    <f:param name="language" value="de" />
</h:commandButton>
<h:commandButton value="Français" action="#{localeSelector.change}">
    <f:param name="language" value="fr" />
</h:commandButton>

with

public void change() {
    locale = new Locale(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("language"));
    // ...
}

(you can also let JSF automatically set it by a @ManagedProperty("#{param.language}"), but this requires the bean to be request scoped, or a <f:viewParam>, see also ViewParam vs @ManagedProperty(value = "#{param.id}"))


Enough ways to pass a parameter from view to controller. Take your pick. The <h:inputHidden> serves in JSF context a somewhat different purpose and it can only be manipulated by JavaScript in the onclick which is ugly.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you for complete answer! I didn't took advantage of EL 2.2 because there seem to be no method in Seam LocaleSelector class that takes locale as a parameter. I've also tried , but it didn't work because the parameter was not bind with localeSelector.language (or maybe I am missing something in these cases?). Anyway solved my problem – Serga Oct 24 '12 at 13:52
  • You're welcome. I didn't expect `#{localeSelector}` to be a Seam-proprietary bean (I don't do Seam). I just assumed outright standard JSF with full control over own code. – BalusC Oct 24 '12 at 13:54
  • Yes, I got that - I should make it clear in my post. I just wanted to clarify. Thanks again) – Serga Oct 24 '12 at 14:34