perissf
perissf

Reputation: 16273

Language switcher implementation in JSF

I have a complex jsf page with some widgets developed in PrimeFaces. Up to now, the application is completely ajaxified, meaning that there aren't submits, but all the events and updates are handled through Ajax behavior (this is not a must, but a nice-to-have feature). I have also done a SelectOneMenu for switching the language:

<h:form>
    <p:panelGrid columns="2" >
        <h:outputText value="#{msgs.SelectLanguage}" />
        <p:selectOneMenu value="#{languageSwitcher.selectedLanguage}" >
            <f:selectItems value="#{languageSwitcher.languages}" ></f:selectItems>
        </p:selectOneMenu> 
    </p:panelGrid>
</h:form>

The switcher works well. My problem is how to reload the translated messages when a language is selected.

I have tried these options:

Option 1

With an ajax update inside the selectOneMenu:

<p:ajax update="myFormsTobeUpdated" ></p:ajax>

This works great, and is the preferred solution because it's Ajax, but

EDITED

this solution doesn't ajax-update the Tab titles in the PrimeFaces TabView, and this is problem is blocking because the Tab titles need to be translated.

Option 2

With a complete reload of the page in Javascript. I have tried this but doesn't work (can't tell why):

<p:selectOneMenu value="#{languageSwitcher.selectedLanguage}" onchange="window.location.reload()" >

Option 3

With a complete reload of the page in Java like explained here: https://stackoverflow.com/a/1821708/870122 (to be honest I haven't tried it yet, but will do soon!)

Any suggestions are welcome.

Upvotes: 1

Views: 4996

Answers (3)

user4107406
user4107406

Reputation:

In your Form:

<h:selectOneRadio   value="#{localeBean.language}"
                        onchange="submit()">
                        <f:selectItems value="#{collection.listLangs()}" var="s"
                            itemLabel="${s.description}" itemValue="${s.code}" />
                    </h:selectOneRadio>

but your not have a collection (REMEMBER, IN YOUR FORM):

<h:selectOneMenu value="#{localeBean.language}"
                                        onchange="submit()">
                                        <f:selectItem itemValue="en" itemLabel="English" /> 
                                        <f:selectItem itemValue="es" itemLabel="Español" />
                                    </h:selectOneMenu>

IN Primefaces, use this: p:selectOneMenu


In your Bean:

import java.lang.invoke.MethodHandles;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@ManagedBean
@SessionScoped
public class LocaleBean {

    private static final Logger LOG = LogManager.getLogger(MethodHandles.lookup().lookupClass());

    private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void setLanguage(String language) {
        LOG.info("Vamos a Cambiar a: " + language);
        locale = new Locale(language);
        LOG.info("Vamos a Cambiar a: " + locale.getDisplayName() + FacesContext.getCurrentInstance().getViewRoot());
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }



}

Upvotes: 0

perissf
perissf

Reputation: 16273

Since with Option 1 it's not possible to ajax-update the Tab titles in the PrimeFaces TabView, I have switched to Option 2, a complete reload of the page using JavaScript.

The code that makes it work is:

<h:form id="selectLanguage">
    <p:panelGrid columns="2">
        <h:outputText value="#{msgs.SelectLanguage}" />
        <p:selectOneMenu value="#{languageSwitcher.selectedLanguage}" onchange="document.getElementById('selectLanguage').submit();" >
            <f:selectItems value="#{languageSwitcher.languages}" ></f:selectItems>
        </p:selectOneMenu> 
    </p:panelGrid>
</h:form>

Upvotes: -1

BalusC
BalusC

Reputation: 1108642

If you're using at least PrimeFaces 3.2, then you can use

<p:ajax update="@all" />

to update the entire view. Before this version, the @all wasn't supported.

Upvotes: 4

Related Questions