1

I have in the header.xhtml change language selectOneMenu. Which by choosing changes the language properly of any xhtml file. But there are few pages where the language strings are set in the Java class itself which is invoked by the Post-Construct.

Header.xhtml

<h:selectOneMenu value="#{client.language}" onchange="submit()" >
<f:selectItems value="#{client.languages()}" />
</h:selectOneMenu>

In the managed bean, I have ViewScoped and then the PostConstruct. My problem here is- after changing the language from the menu, some string set by the Java are not translated. That's because it is invoked by the PostConstruct which is not invoked when the language is changed. But when I goto that page by clicking the link, then the strings are translated. Its just that as soon as I change language the strings aren't translated.

I think the problem here is because the PostConstruct is not invoked when the language is changed. How do I invoke it?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Sayan
  • 119
  • 2
  • 8
  • A method decorated by `@PostConstruct` is invoked before the bean class is put into service. A view scoped bean lives as long as a view posts back to itself i.e. when you submit the form to the same view. After you make a `GET` request to a view scoped bean, a method decorated by `@PostConstruct` in that view scoped bean will not be invoked in the subsequent `POST` requests (until you recreate the view scoped bean - by navigating to a different view, for example). – Tiny Dec 29 '14 at 22:43
  • `onchange="submit()"` essentially makes a `POST` HTTP request. Thus, the the method annotated by `@PostConstruct` in the view scoped bean will not be invoked, since the view happens to post back to itself. – Tiny Dec 29 '14 at 22:43
  • Thanks! If I change onchange="submit()" to something else the @PostConstruct will be invoked? – Sayan Dec 30 '14 at 14:39
  • This is already mentioned in the answer below (Luiggi Mendoza), "*after changing the language, the best option is to fire a new non-ajax request-response cycle to the server*". See also [this](http://stackoverflow.com/q/5388426/1391249) and [this](http://stackoverflow.com/q/14373153/1391249). – Tiny Dec 30 '14 at 17:33
  • What I did in my application was : Since I happen to use PrimeFaces, it makes the life much easier. Supported languages are listed in a ``. When a language from this `` is selected/changed, the `onchange` JavaScript event is triggered and the selected language name is passed as a parameter to a JavaScript function just like this `onchange="changeLanguage([{name: 'language', value: this.value}]);"`. This JavaScript event is bound to a ``. – Tiny Dec 31 '14 at 06:02
  • After the selected language is set in a user's session (in a session scoped bean), a redirect is made to the current view including query-string parameters, if any such as `?faces-redirect=true&includeViewParams=true`. – Tiny Dec 31 '14 at 06:02
  • Nope. Not working! But thanks for the info. – Sayan Jan 02 '15 at 20:24

2 Answers2

3

Your question is basically about the behavior of @PostConstruct. This method will be called once after the bean has been created and after the injection of fields has happened e.g. fields decorated with @EJB and @Resource annotations.

Since you use @ViewScoped bean, then this will be created once per view. Refreshing the page will create a new view, that's why your instance of the @ViewScoped bean will be recreated and you will process the data in the desired language.

Possible solutions:

  • Mark the bean that handles the view as @RequestScoped.
  • Use proper i18n internationalization for your output messages. Do not rely on messages being constructed from your managed bean.

In my case, I would use the latter rather than the former. Also, after changing the language, the best option is to fire a new non-ajax request-response cycle to the server.

More info:

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
1

I have tried to do it like you did in the past with no luck either. Here is how I work around the problem (using JQuery):

<h:selectOneMenu value="#{client.language}" onchange="$(document).find('.submitBtn').click();" >
     <f:selectItems value="#{client.languages()}" />
</h:selectOneMenu>

<h:commandButton style="visibility: hidden;" styleClass="jsfHidden submitBtn" action="#{yourpostconstructmethod}"/>
user2980252
  • 69
  • 1
  • 7