Since upgraded to JSF2.0, Client ID:FormID:ComponentID being preceded to the validation message while using f:validateDoubleRange - jsf

I have upgraded from JSF 1.1 to JSF 2.0. Earlier I was using f:validateLongRange or f:validateDoubleRange and the validation worked fine. However, since I have migrated to JSF 2.0 the validation message precedes with client ID which looks something like below :
FormID:ClientID:0:ComponentID in my case, the message appears as
premiumCategory:j_idt368:0:tlNewLOS: Validation Error: Specified attribute
is not between the expected values of 1 and 999,999.
There is a Jira which talks about prefixing ClientID but I dont think its of any use to me.
I learnt from the blog Communication in JSF 2.0 these tag handlers do not work correctly in JSF 2.0 thus we should create custom validators using f:validator
I followed BalusC’s answer from here; The only difference was I did not get my max and min values from the bean, I specified them in the xhtml,it still printed the validation message as stated above.
While debugging I realised that the client ID is generated as FormID:ClientID:0:ComponentID and is stored in the UIComponent instance which gets passed to the MessageFactory.getMessage method.
The same blog which I mentioned before has a topic in it saying "Ajax rendering of content outside form" which I thought would have a solution to my issue, but again no luck.
Now I have my own custom validator class which extends to DoubleRangeValidator and overrides validate method. I get the desired message. However, I am not convinced that writing a custom validator for each f:validatorXXXX component is the solution.
I am still on my learning curve, can anyone explain me why and where MessageFactory.getMessage binds these IDs to to the faces message?
Please advise,
Dakshata Gulkhobare

The label is overrideable by setting the label attribute on the input component of interest.
<h:inputText ... label="Your label" />
This way the validation message will be formatted as follows:
Your label: Validation Error: Specified attribute
is not between the expected values of 1 and 999,999
Otherwise it will indeed default to the component's client ID.
If you happen to use <h:outputLabel> already and would like to use exactly its value, but don't want to duplicate it into the label attribute of every single input component, then you may find OmniFaces <o:outputLabel> helpful.

Related

Required asterisk is not displayed in input fields Primefaces 6.0

I have created a form using Primefaces 6.0 and in the bean I have used constrained validators like #NotNull and #NotEmpty in the bean fields. However the asterisk near the label of the input text are not automatically rendered. The asterisk is only displayed when I set and an inputText as "required=true". My problem is that I would like to use the validation messages provided by the bean validation JSR so I would not like to put "required"to the input texts. I have also read that after primefaces 5.0 the validation constraints are automatically detected and the asterisk is rendered automatically. Has anyone faced a similar problem? Have I missed any configuration?
i think whatever you want is possible by some custom code, use CSS for asterisk (*) in read color, do not put required=true use custom validate. have look https://www.primefaces.org/showcase/ui/csv/custom.xhtml
if you did not put required=true your form will submmited to bean and you have to check and bean level for validation.
That is a nice to have feature that doesn't exist (yet).
If you want it implemented, log an enhancement feature.
Or extend bean validation component ;-)

Using binding attribute causes javax.faces.FacesException: Cannot find component with identifier

I have a problem I can't quite get a handle on.
First the context: I am developing a web application using Primefaces 3.5 (yes, unfortunately I am stuck with this old version for now), running on JBoss 7.
There is a form with id "form" encompassing all following xhtml code.
I have a component in my view which is provided by usage of the binding attribute:
<p:dashboard id="dashboard" binding="#{myBackingBean.dashboard}" />
Then sometimes I would like to perform an ajax update on this component, this is done by using the RemoteCommand component of primefaces:
<p:remoteCommand
actionListener="#{myBackingBean.someActionListener()}"
process="#this" id="myRmtCmd" oncomplete="myJsFunction();"
update=":form:dashboard" name="myRemoteCommand" />
The RemoteCommand is triggered by a clicking on a Link:
Some Text
This works pretty well so far. However after deploying this code to production I sometimes get a FacesException:
javax.faces.FacesException: Cannot find component with identifier ":form:dashboard"
referenced from "form:myRmtCmd".
This is where my problem lies because I cannot reliably reproduce this exception. My question is this: What could lead to this exception being thrown? It seems to work 95 % of the time but being the perfectionist I am (and many of you reading this are as well, I'm sure ;) ) I would like this code to work 100 % of the time. What am I missing?
Before answering please consider these constraints:
yes, i have to use the binding attribute for providing the dashboard as I need a great deal of control over what gets added to the component
to avoid using IDs I also tried updating the dashboard by its css class via one of primefaces' advanced selectors: #(.ui-dashboard) - this also does not work!
yes, it would be possible to use a commandbutton/link instead of wiring up the remotecommand component to a simple html link but in this case the link is rendered by a JSF renderer component and I made some bad experiences with dynamically adding buttons etc (due to JSF Spec Issue 790)
Cheers,
p.s.
I also had this weird behavior.
There are probably more than one component bindded to #{myBackingBean.dashboard}, so the first one sets the id and there will be no one called "dashboard".

Customize bean validation message?

Two stupid questions about bean validation used in JSF:
How can I remove the prefix form1:userName: from the output message?
<h:message for="userName" />
Which gets:
form1:userName: Please enter a valid username (5-20 characters)
I‘d also like to translate the name form1:userName to User Name, it's easy to implement such translation but I can't find where to build the message.
I have a custom validator, say #CreditCard, its default message is {foo.bar.BadCreditNumber}
#interface CreditCard {
String message() default "{foo.bar.BadCreditNumber}";
}
And the message is defined in foo/bar/ValidationMessages.properties in classpath. Now how can I make this properties file loaded in every page?
Concerning 1: The error message's format depends on the property javax.faces.validator.BeanValidator.MESSAGE which must be specified in a resource bundle of the application like this:
javax.faces.validator.BeanValidator.MESSAGE={1}: {0}
The placeholder {0} refers to the error message as created by the Bean Validation runtime, {1} refers to the component label. So if you don't want to have the label within the message, just make sure that the placeholder {1} isn't contained within that property value.
More information can be found in the JSF 2 spec. section 3.5.6.3.
Concerning 2: It's as BalusC is saying, just put ValidationMessages.properties to the root of your classpath. More information can also be found in the Hibernate Validator reference guide.
Use the input element's label attribute.
<h:inputText label="User name" ... />
See also JSF 2.0 tutorial - Finetuning validation.
The ValidationMessages.properties file has to be placed in the classpath root, without any package. See also JSR-303 specification.

Is the ID generated by JSF guaranteed to be the same across different versions and implementations?

We are about to write a full set of tests for one of our JSF applications using Selenium.
So far, it seems that there are two preferred approaches to uniquely identify each element: by ID or using a unique class name. The later is really a hack and doesn't make sense semantically. The former is the right approach, but the element IDs are generated by JSF.
All the different JSF implementations I've seen seem to be using the same approach: use the parent element as the namespace and then concatenate the element ID using a colon. Fair enough.
The question is: do you know if this is guaranteed in some part of the JSF specification? It'd be a real problem to find out later that we need to rewrite all the component selectors in the tests just because JSF x.y changed the way it generates the ID names.
Thanks!
JSF usually generated the ID of components, if ID attribute is not explicitly mentioned.
It will be generated in the format j_idXXX (XXX will be number incremented)
<h:form id="LoginForm">
<h:inputText id="userName" .../>
</h:form>
for this inputText the id will be formed as LoginForm:userName and if id is not mentioned explicitly,then it will be formed something like LoginForm:j_id15
This is mentioned in JSF specification in section 3.1.6, But the exact format is not specified though.
The clientId is generated using this method UIComponent.getClientId(); Follow this link UIComponent
Is the ID generated by JSF guaranteed to be the same across different versions and implementations?
No. You've to explicitly specify the component ID on the UIInput component of interest and all of its parent UINamingContainer components such as <h:form>, <ui:repeat>, <h:dataTable>, etc yourself. Those IDs will by default be woodstocked using separator character :.
However, the separator character is in turn configureable since JSF 2.0. So, if you change the separator character for your webapp from : to - or something, then you'd have to rewrite the selenium tests which are relying on the HTML element IDs.
From the JSF (2.1) spec:
The client identifier is derived from the component identifier
(or the result of calling UIViewRoot.createUniqueId() if there is
not one), and the client identifier of the closest parent component
that is a NamingContainer according to the algorithm specified
in the javadoc for UIComponent.getClientId(). The Renderer
associated with this component, if any, will then be asked to convert
this client identifier to a form appropriate for sending to the
client. The value returned from this method must be the same
throughout the lifetime of the component instance unless setId() is
called, in which case it will be recalculated by the next call to
getClientId().
Aside from the spec, 3rd party plugins can affect the client identifier (e.g. protlet bridge APIs)

Displaying custom error message for a blank field in a simple JSF application

I was trying out a simple JSF application, in which I need to check if the "name" field is blank, then display an error message.
The code which takes the field's value is:
<h:outputLabel value="Name"/>
<h:inputText value="#{greeting.name}" required="true">
<f:validator validatorId="NumValidator"/>
</h:inputText>
The control of the program does not go into the validator class, if the field is submitted without entering anything, and it displays the default error message:
j_id_jsp_869892673_1:j_id_jsp_869892673_4: Validation Error: Value is required.
How do i display a custom message for this ?
The Message.properties file stored the default validation messages. This file is contained in the JAR of the JSF implementation library.
If you look at the content of this file, regarding the required validation, you will see that:
javax.faces.component.UIInput.REQUIRED={0}: Validation Error: Value is required.
To define your own error messages, create a new properties file, add the adequate error message, for example:
javax.faces.component.UIInput.REQUIRED=Hey, you forgot to fill the input {0}!
(note that {0} will be replaced by the ID of the field)
then, in your faces-config.xml, define a new message-bundle:
<message-bundle>package.that.contains.the.properties.file</message-bundle>
So for example, if your my-messages.properties is stored in the foo/bar package, you will have to write:
<application>
...
<message-bundle>foo.bar.my-messages</message-bundle>
</application>
(note that you will not have to specify the .properties extension)
The way suggested by romaintaz is definitely way to go.
On the other hand if you are looking for more customization, you can use a phase listener that fires before render response phase as does some customizing.
For example first define the value for key as below:
javax.faces.component.UIInput.REQUIRED=INPUT_REQ_FAIL
then for input components that require validation have them pass a attribute using f:attribute .Then in phase listener iterate over the face messages and check for INPUT_REQ_FAIL and replace it with cutom message along with the attribute value for the component.
I think you should look at JSR 303! This is fully standard based user input, it works out of the box with JSF 2 (I use My Faces). And the nice thing is, no need for xml or properties files to specify custom messages.

Resources