Why I am getting MissingResourceException locale en_US when I have defined default locale as es_ES? [duplicate] - jsf-2

i wanted to set the default location of my jsf web project to english, so
i did the following:
faces-config.xml
<application>
<locale-config>
<default-locale>en_EN</default-locale>
<supported-locale>de_DE</supported-locale>
</locale-config>
<resource-bundle>
<base-name>de.hof.tschuwwa.resources.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
i have a package in my src folder de.hof.tschuwwa.resources and inside
of that package i have two property files:
messages_de_DE.properties
messages_en_EN.properties
and i tested it in a small xhtml file:
<h:body>
<ui:composition template="/templates/master.xhtml">
<ui:define name="header">
<h:form>
<h:commandButton action="#{navigationService.toLogin}" value="#{msg['login']}" />
<h:commandButton action="#{navigationService.toRegister}" value="#{msg['register']}" />
</h:form>
</ui:define>
</ui:composition>
</h:body>
When i start my application it shows the german values and not
the english values. i wanted the default language to be english.
How can i set my default language? The faces-config.xml default-locale
does not seem to work.
Also i need to know how i can change my localization. i wrote this small
service:
#Named
#SessionScoped
public class LanguageService implements Serializable {
private static final long serialVersionUID = 1L;
public void changeLanguage(String language) {
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(language));
}
}
and tried out with the following buttons inside a form:
<p:commandButton id="english" value="English" action="#{languageService.changeLanguage('en')}" immediate="true" />
<p:commandButton id="german" value="Deutsch" action="#{languageService.changeLanguage('de')}" immediate="true" />
but nothing happened when i used them.

<default-locale>en_EN</default-locale>
First of all, you've there a mistake in the locale identifier en_EN. The first two lowercase characters represent the ISO 693-1 language code. It is optional and only required whenever the country code is present. The last two uppercased characters represent the ISO 3166-1 Alpha-2 country code. It is optional and often only used to distinguish between country-specific language dialects, like American English (en_US) and British English (en_GB). There's no such country like "England", so en_EN is definitely invalid. You most likely want to use en or perhaps en_US here.
Thus, so
<default-locale>en</default-locale>
with an appropriate messages_en.properties file.
How can i set my default language? The faces-config.xml default-locale does not seem to work.
The <default-locale> is only used when the client didn't supply the locale by itself in flavor of the Accept-Language HTTP request header, or supplied one which isn't supported by the application as definied in <supported-locale>. A lot of (sane) clients actually set the Accept-Language header. With a HTTP traffic monitor you can see them.
(the screen says: en-US is the first preference (with a default "weight" of 1), the en is the second preference with a "weight" of 0.8, the nl is the third preference with a "weight" of 0.6; in Chrome you can change this in chrome://settings/languages by adding/removing/reordering languages).
If you want to prevent this and want to force the "default" locale for some unclear reason, then you'd need to explicitly set the <f:view locale> to the desired "default" locale (note: you're thus actually overriding client's preferred locale as configured in its program — the webbrowser).
E.g.:
<f:view locale="#{languageService.language}">
(just put in master template, wrapping the <h:head> and <h:body>)
with this new property in your backing bean:
#Named
#SessionScoped
public class LanguageService implements Serializable {
private Locale locale;
#PostConstruct
public void init() {
locale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
}
// ...
}
Also i need to know how i can change my localization.
Your mistake in this particular example is that you're not updating the view after invoking the action. You need to add update="#all" to the command buttons. But there's another mistake: you're not remembering the locale for subsequent requests. It would fall back to the "default" locale again. You need to set the <f:view locale> with this property. This is already answered in detail before: Localization in JSF, how to remember selected locale per session instead of per request/view.

Related

Getting correct parent ID in composite components

For partial updating my composite components, I have some problems finding the correct parent IDs. e.g. if my component is inside of a tabView
<p:tabView id="foo">
<p:tab>
<stg:mycomponent id="bar" />
</p:tab>
</p:tabView>
Now I need the String :foo:bar to find the correct parts, that I want to update. Via #{cc.id} I just get bar, so this does not work for me.
However, I tried to achieve this by some kind of dirty hack by adding a attribute to my component like this
<composite:attribute
name="parentId"
default=":#{component.namingContainer.parent.namingContainer.clientId}"
/>
If I hand over the String :foo:bar to parentId everything works fine, but of course that's not what I really want to do. I do not want to force the user of my component to hand over this ID.
But now the problem: If I do not hand over a parentId, I only can use my attribute in the "first level" of my component. If there are some kind of "nested IDs" then #{cc.attrs.parentId} is evaluated e.g. to foo:bar (which is nice) but also foo:bar:fooBar or somethin like that, depending on where #{cc.attrs.parentId} is located in my code.
I hope it's comprehensible what my problem is and what I am exactly asking for. If not, please leave a comment.
I am using primefaces 3.5 and JSF 2.1 (Mojarra)
If I understand, you need to update parts of a composite component within the composite component itself. Normally you don't need to know the parents IDs to achieve this.
As you are setting id on a primefaces component, you can update it with primefaces using the same id (without any :container:etc prefix) as long as your update is in the same scope.
Here is an example (see source below).
Observe the generated id's in the HTML page produced by JSF in the first tab:
First span : id="static" (raw html id, not PF, not unique in the document)
Second span : id="myform:tv1:comp1:static2" (PF-generated to ensure id is unique in the document)
Third span : id="myform:tv1:comp1:dynamic" (PF-generated, unique)
poll component use the id "myform:tv1:comp1:dynamic", even if we only provide "dynamic" in the source.
The parents does not need to know the ID of the component part to be updated
The component does not need to know the IDs of its parents/containers
Please note generated IDs on the second tab. PrimeFaces does its job by naming them unique.
Sample composite component:
<composite:interface>
<composite:attribute name="label" />
</composite:interface>
<composite:implementation>
<h1><h:outputText value="#{cc.attrs.label}"/></h1>
<span id="static1">
Static : #{testBean.increment}
</span>
<p:outputPanel id="static2">
Static : #{testBean.increment}
</p:outputPanel>
<p:outputPanel id="dynamic">
Dynamic : #{testBean.increment}
</p:outputPanel>
<p:poll interval="3" update="dynamic" />
</composite:implementation>
Use the component in a XHTML page:
<h:form id="myform">
<p:tabView id="tv1" >
<p:tab id="tab1" title="First Tab">
<comps:myComponent id="comp1" label="Abc" />
</p:tab>
<p:tab id="tab2" title="Second Tab">
<comps:myComponent id="comp2" label="Def" />
</p:tab>
</p:tabView>
</h:form>
And this is the code for the test bean:
#ManagedBean(name="testBean")
public class TestBean implements Serializable
{
static int _counter = 0;
public String getIncrement()
{
_counter++;
return Integer.toString(_counter);
}
}
I hope this example will be clear enough and close to what you want to get.
Please let me know.

<h:selectOneRadio> dynamic Value to Backing Bean

I have written a piece of code to put two pairs of radio button in a *.xhtml page of a JSF project built in JSF2.0, Jboss As 7.1.1 final and JDK 6.0, PrimeFaces 3.4.2.
<h:panelGrid columns="2">
<h:selectOneRadio value="#{calendarBean.radioFirst}">
<f:selectItem id="morning" itemValue="morning" itemLabel="Morning"/>
<f:selectItem id="afternoon" itemValue="afternoon" itemLabel="Afternoon"/>
</h:selectOneRadio>
<h:selectOneRadio style="padding-left: 170px" value="#{calendarBean.radioSecond}">
<f:selectItem id="noon" itemValue="noon" itemLabel="Noon"/>
<f:selectItem id="endofday" itemValue="endofday" itemLabel="End Of Day"/>
</h:selectOneRadio>
</h:panelGrid>
The Bean is:
private String radioFirst="morning";
private String radioSecond="endofday";
public String getRadioFirst() {
return radioFirst;
}
public void setRadioFirst(String radioFirst) {
this.radioFirst = radioFirst;
}
public String getRadioSecond() {
return radioSecond;
}
public void setRadioSecond(String radioSecond) {
this.radioSecond = radioSecond;
}
I have written a method to invoke on a Action Event where I want to have the values of the radio button selected. when the method invokes I get the value of the radio buttons as "morning" and "endofday" as these two are the initial values of the bean variables.
private String radioFirst="morning";
private String radioSecond="endofday";
But if I change the radio button options, I don't get the updated values, its the same old initial values. How can I get the changed values? Please help!
Three things
Don't use the session scope for this usage scenario. This will go completely wrong when your users open the same page in more than one tab. Use request scope or view scope.
Use a regular action instead of an action listener, and don't provide the radio button values as attributes. This makes no sense. The selectOneRadio components will set the updated values on your backing bean. When your action method is invoked, you will have access to those values via the instance fields of your bean.
Leave out the window.reload. If you need a full page refresh after the action, set ajax to false on the p:commandButton or use an h:commandButton.
You should modify your action button like this :
<p:commandButton actionListener="#{userLeaveBean.addAppliedLeave}" styleClass="apply_button" value="Create Leave">
<f:attribute name="userId" value="#{employee.name}"/>
</p:commandButton>
As #MikeBraun suggested, remove the window.reload(). If you want to refresh something, you could do it by using the update attribute from the p:commandButton.
And modify your bean according to this :
#ManagedBean
#SessionScoped // Could probably be moved to #RequestScoped or #ViewScoped
public class UserLeaveBean
{
#ManagedProperty(value="#{calendarBean}")
CalendarBean calendarBean;
public void setCalendarBean(CalendarBean calendarBean)
{
this.calendarBean = calendarBean;
}
public void addAppliedLeave(ActionEvent event)
{
System.out.println("Radio 1 : " + calendarBean.getRadioFirst());
System.out.println("Radio 2 : " + calendarBean.getRadioSecond());
}
}
The ManagedProperty will get the other bean accessible for you by injecting it inside the current one. Use the proper scope, probably you are using SessionScoped because you are using window.reload().
Important : the ManagedProperty bean must be at least scoped the same length as the other bean.
Read more :
Injecting Managed Beans in JSF 2.0
PrimeFaces Showcase - commandButton

Primefaces outputLabel for composite component

I have an issue with using p:outputLabel when used with composite component. I have composite component with p:inputText field (I removed irrelevant parts from component):
<cc:interface>
<cc:editableValueHolder name="myInput" targets="myInput"/>
<cc:attribute name="required" required="true" type="java.lang.Boolean" default="false"/>
</cc:interface>
<cc:implementation>
<p:inputText id="myInput" required="#{cc.attrs.required}"/>
</cc:implementation>
Now, I wont to use this component with p:outputLabel:
<p:outputLabel for="myComponent:myInput" value="#{resources['myLabel']}:"/>
<my:myComponent id="myComponent" required="#{myBean.required}"/>
Everything works fine, required validation, message is displayed as well, but there is no * sign on label, as there is when I connect label directly to p:inputText component. If I, on the other hand, hardcode required="true" on p:inputText everything works fine.
I debugged through org.primefaces.component.outputlabel.OutputLabelRenderer and discovered that component is recognized as UIInput, but input.isRequired() returns false. Farther debugging discovered that required attribute isn't yet defined on component, so it returns false as default value i UIInput:
(Boolean) getStateHelper().eval(PropertyKeys.required, false);
Also, if I just move p:outputLabel inside composite component everything works fine. Like EL is evaluated later inside composite component?
I'm using Primefaces 3.5 with Mojarra 2.1.14
This is, unfortunately, "by design". The evaluation of the #{} expressions is deferred to the exact moment of the access-time. They're unlike "standard" EL ${} in JSP not evaluated at the exact moment they're been parsed by the tag handler and "cached" for future access during the same request/view. At the moment the <p:outputLabel> is rendered, and thus the #{cc.attrs.required} as referenced by UIInput#isRequired() needs to be evaluated, there's no means of any #{cc} in the EL context. So any of its attributes would not evaluate to anything. Only when you're sitting inside the <cc:implementation>, the #{cc} is available in the EL context and all of its attribues would thus successfully evaluate.
Technically, this is an unfortunate corner case oversight in the design of <p:outputLabel>. Standard JSF and EL are namely behaving as specified. Basically, the presentation of the label's asterisk depending on the input's required attribute should be evaluated the other way round: at the moment the <p:inputText> inside the composite is to be rendered or perhaps even already when it's to be built. Thus, the label component should not ask the input component if it's required, but the input component should somehow notify the label component that it's required. This is in turn hard and clumsy (and thus inefficient) to implement.
If moving the label to inside the composite is not an option, then your best bet is to create a tag file instead of a composite component around the input component. It only requires some additional XML boilerplate.
/WEB-INF/tags/input.xhtml:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
>
<c:set var="id" value="#{not empty id ? id : 'myInput'}" />
<c:set var="required" value="#{not empty required and required}" />
<p:inputText id="#{id}" required="#{required}"/>
</ui:composition>
/WEB-INF/my.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>input</tag-name>
<source>tags/input.xhtml</source>
</tag>
</facelet-taglib>
/WEB-INF/web.xml:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
Usage:
<html ... xmlns:my="http://example.com/my">
...
<p:outputLabel for="myInput" value="#{resources['myLabel']}:" />
<my:input id="myInput" required="#{myBean.required}" />
I just did a quick test and it works fine for me.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

PrettyFaces error with required attribute

I'm developing a web application using JSF 2 and prettyfaces. I annotated one of my #ViewScoped beans with pretty annotations. That's what I have:
#ManagedBean
#ViewScoped
#URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId}",
viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")
public class NavegableAppView extends SystemNavegable {
/**
Basically that shows the details of an application which is installed in my system. This bean can be instanced in two ways, passing #{appId} param, which indicates the id of the application which I want to load, or without that param, in this case the bean will recover this id from a #SessionScoped bean.
That's how the page /system/manage_app/content/app_detail/app_detail.xhtml is managing the parameter:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
template="/templates/general_template.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam id="appId" name="appId"
value="#{navegableAppView._ParamApp}" required="false" />
<f:event type="preRenderView"
listener="#{navegableAppView.initialize}" />
</f:metadata>
</ui:define>
<ui:define name="general_content">
<p:panel>
<!--More stuff-->
The problem here is I want NavegableAppView bean to be created, with or without param. I have tried this way <p:button value="prueba" outcome="pretty:app-view" /> which works but limits me to do nothing more than outcome and also <p:commandButton value="prueba2" action="pretty:app-view" ajax="false" />, which is the equivalent to call an action method and return the navigation case (that's what really I want).
First choice creates the bean properly and loads the value from the session. Second case, is giving me this error:
HTTP 500 - PrettyFaces: Exception occurred while building URL
for MappingId < app-view >, Required value < #{appId} > was null
So my target bean is not getting constructed. I have tried adding the parameter manually to the navigation case: return pretty:app-view?appId=1 and it works, but I want the target bean to recover it from the session itself. Do I have to call a redirect or something like that in my action method?
Pool your ideas.
So you are actually running into one of the "edge" effects of PrettyFaces. The "appId" parameter you have defined is actually treated both a parameter name, and also an EL bean value location for building links.
#URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId}",
viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")
When you use the postback-action navigation functionality of PrettyFaces, it requires an EL bean name. Now, it just so happens that since you have not provided one in your #URLMapping annotation, that PrettyFaces is going to try to use the parameter name anyway, and hope that it can find what you want. In this case, obviously, there is no bean value called #{appId}.
You're really mixing two types of functionality that attempt to solve the same problem. Your <f:metadata> and <f:viewParam> definitions are doing the same thing that PrettyFaces does with its path-parameters and action methods. You should use one or the other mechanism. If you really want to mix them, then as you said, you should be invoking actual navigation from your <h:commandButton>, like so:
<p:commandButton value="prueba2" action="#{navegableAppView.goToAppId}" ajax="false" />
Then, you'll need to make sure you return a valid JSF2 navigation string WITH the appId parameter, such as:
public String goToAppId() {
return "/system/manage_app/content/app_detail/app_detail.xhtml?faces-redirect=true&appId=" + appId";
}
PrettyFaces will then understand that you are redirecting to a URL that has been mapped, and will perform outbound rewriting on the URL, and send you to the proper, /detail/#{addId} instead. This is all in the docs.
The final option would simply to remove the <f:metadata> and <f:viewParam>, and use the built-in PrettyFaces functionality for managing view parameters instead. Simply removing the metadata and updating your #URLMapping to this, would solve your problem:
#ManagedBean
#ViewScoped
#URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId : navegableAppView._ParamApp}",
viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")
public class NavegableAppView extends SystemNavegable {
#URLAction
public String initialize() {
if ( appId != null ) {
this.item = appsDB.findById(appId);
return null;
}
// Add a message here, "The item {..} could not be found."
return "pretty:app-list";
}
This is how you initialize pages using PrettyFaces. When it comes down to it, if you are using pretty:mappingId navigation, you should only use PrettyFaces features. If you are going to use normal JSF2-style navigation where you specify the view-id and all the parameters of the URL, then you can mix-and match (as long as you are using named path-parameters in your URL mappings.
I hope this helps.

JSF 2 ajax behavior event listener not firing on a Date

I am having a problem with an ajax behavior event not being fired immediately as text is typed in a field.
If the field is a String no problem, but I am using a Date.
xhtml:
<h:outputLabel value="Date of Birth:" />
<h:inputText id="searchDOB" value="#{search.dob}" required="true">
<f:ajax event="keyup" listener="#{search.addHyphensToDOB}" render=":output" />
<f:convertDateTime pattern="dd-MMM-yyyy" />
bean:
Date dob;
public void addHyphensToDOB(AjaxBehaviorEvent abe) {
System.out.println("addHyphen");
}
The event is only fired after typing the following:
22-JAN-
And fires on any number after the second hyphen, but not before.
One solution could be to change the Date type to a String, then format without using converter, but I would like to keep the Date type.
Any suggestions, thanks.
Eclipse 3.7, tomcat 7, jsf2.1,
It's not fired because a conversion error has occurred due to invalid date format. The submitted value is converted everytime before the bean listener method is hit. Add a <h:message>/<h:messages> and include its ID in <f:ajax render>. You'll then see it.
A String value of for example 2 can impossibly represent a valid Date object when parsed with the pattern dd-MMM-yyyy.
You'll really need to keep it a String if you want to achieve the functional requirement this way. As a completely different alternative, you could consider to do it entirely at the JavaScript side without sending JSF ajax requests.

Resources