JSF 2.0 Displaying all validation messages of multiple validators - validation

I have an h:inputText element with more than one validators, eg.:
<h:inputText id="myId" value="#{some.value}">
<f:validator validatorId="validatorOne/>
<f:validator validatorId="validatorTwo/>
</h:inputText>
<h:message for="myId"/>
Now if I implement my validators to throw a ValidatorException, the second validator won't run, even if it would fail as well.
But I'd like both validators to run and to diplay both error messages in case both validations fail.
I've already tried not to throw ValidatorException like this:
facesContext.addMessage(uiComponent.getClientId(), facesMessage);
((UIInput)uiComponent).setValid(false);
But the h:message won't display both of the error messages, although I can see them if I use h:messages.
How is it possible to display all validation error messages?

That's the way how JSF validators are specified to work. The validators are fired in the order they're declared on the component and if one of them fails, then the remnant won't be fired.
If using <h:messages> is really not an option for some unclear reason (perhaps you weren't aware about its for attribute which works the same way?), then your best bet is creating another validator which in turn delegates to the both validators and merges the caught validator exceptions into one.

Related

Conditional validation without binding attribute

I'm dealing with a legacy code base and come across a situation when it's necessary to validate a field "fieldToValidate" if some other field "otherField" has some value (otherwise field is not validated). However the field "otherField" doesn't have a binding attribute.
I can add a binding and then update code like this:
<h:inputTextarea id="fieldToValidate" value="#{MyBean.fieldToValidate}"
required="#{MyBean.otherField != 'special_value'}" />
However there is a plenty of places where validation should be added and I don't want to modify backing beans. Is there a way to implement validation without adding "binding"?
Validation with some JS library is not a option.
You do not necessarily need to bind it to a bean property. Just omit the MyBean. part to bind it to the view scope directly.
<h:selectOneMenu binding="#{otherField}" ... />
...
<h:inputTextarea ... required="#{otherField != 'special_value'}" />
See also:
JSF component binding without bean property
What is component binding in JSF? When it is preferred to be used?

JSF 2 and manual validation with JSR 303 - how to track fields?

I want to use JSR 303 (Hibernate Validator) in my JSF 2 project. However, I have complicated forms and field-level validation is not sufficient. I need to use many #ScriptAssert annotations at class-level of my model and its child beans.
So I want to validate form models manually (inside bean action method for example). But I could not understand how I can preserve which validation message should be shown at which field (as it works automatically when field-level validation is on and processed by JSF).
Also I'll need to specify for some of class-level annotations that their messages are to be shown at specific fields. I do not see a straight way to manage it...
Could you please provide a link to explanations of these questions (or tell me that I am doing something wrong?). I think I fail in googling it because internet is bloating with keywords JSF and validation, sorry.
The most idiomatic way to do that is to create custom Bean Validation validator for your class.
You need to create validation annotiation that you would put at the class level (not field level) and associated with that class validator class.
See for instance:
http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/validator-usingvalidator.html (Example "Class level constraint")
How can I validate two or more fields in combination?
Validation inside managed bean is also possible, you can throw in your action methods proper validation exception, but usually it is cumbersome, hard to reuse and mixes business logic code with validation.

How to pass the event parameter when attaching an listener to a composite component

I tried to attach an event-listener to a composite component as follows:
<cc:interface>
<cc:attribute name="listener" method-signature="void listener(javax.faces.event.ComponentSystemEvent)" />
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<h:inputText value="#{cc.attrs.value}">
<f:event type="preRenderComponent" listener="#{cc.attrs.listener}" />
</h:inputText>
</cc:implementation>
with the using page having this:
<ofc:testComp value="#{testAction.testInt}" listener="#{testAction.doWhatever}" />
and the backing bean like so:
public void doWhatever(ComponentSystemEvent event) {
System.out.println(testInt);
System.out.println("I was here");
}
This results in a PropertyNotFoundException: doWhatevercannot be found on testAction When searching the web I found this very similar solution. The main difference here is that the event parameter has been omitted. When I do the same in my scenario, it works (which I find confusing, because the documentation for f:ajax and f:event states the listener must to conform to void listener(AjaxBehaviorEvent) and void listener(ComponentSystemEvent) respectively)
The problem is: I'm trying to do all of this exactly because I need to get back to the original sender of the event via event#getComponent So the question is: Is there a way to pass the event parameter in this kind of setup?
Background: I need to perform some additional validation on a range of fields. Basically, I want to hook into the lifecycle after the model has been updated, perform some calculation and possibly abort before the invoke application phase if values don't fit. The offending field needs to be marked.
I played around with the normal validation mechanism for a while, but the calculation uses the model values, which will not have been updated yet at that point. I am aware, that even if I get the above code running, preRenderView will be too late to stop actions, but I am thinking about keeping an hidden input, which currently does the job of failing validation under the hood, and just adding the listener to actually mark the real offending field. But for this, I need the event ... any ideas?
Thanks in advance.
Update: this answer here uses the same principle, but also runs into problems as soon as the parameter is added - only I get a different error.

Extending JSF validation in application

We are developing a web application based on JSF (v2.0) framework. We need to have custom validations in our application. We decided to extend the JSF validation framework by implementing the Validator class.
So let us say that we have multiple input fields which needs to be validated. These input fields are First Name, Last Name, Email Address. We need the user to enter information in these fields. And email address field will have two validations - Required and isValidEmailAddress.
We should be able to use the custom Required validation in First Name, Last Name and Email Address fields. But each time I want different error messages to be displayed for each field. For example in case of First Name, I want to display First Nameis required. In case ofLast nameI want to displayLast name is required`.
How can I reuse the same Required validation implementation for multiple fields but with different error message? Is it possible to do that in JSF? Could you please let me know?
First of all, you don't need to write your own validation logic for required input in JSF. It's one of the basic amenities provided by the framework itself.
JSF's validation framework is cleanly abstracted from messages related to validation, so the two don't have to depend on each other. Your options:
Each input component has a validatorMessage attribute that allows you specify the text/string that will be displayed to the user on validation error. For your specific use case, JSF has gone one step further to specify the required and requiredMessage attribute for input components; to enforce required input and show messages specifically for required input validation respectively. What this means in your use case is that you don't need to write custom validation logic for required input.
By principle of better design you can configure all your desired validation/conversion error messages in a resource bundle (example here) and reference the entries in the resource bundle within your jsf view.
Implementing the validator interface requires you implement the validate method with the following signature
public void validate(FacesContext ctxt, UIComponent comp, Object value) throws ValidatorException
comp refers to the component being validated from which you can get it's Class, clientId etc. value will provide the submitted value from the component

Converting to long and validate

I have a Facelets page with a form with ICEfaces components. empId is a long type property, which has to be checked if null or not in the bean. It is taken as String in the form, and I am converting that to long type using Long.valueof(empId).longValue(); in order to pass it to DAO to check against DB column.
Is this the way we are supposed to do it? Or are there another ways?
You'd like to use a Long property instead of a String property to enforce automatic conversion to Long by JSF/EL (it has namely builtin conversion for standard Number, Boolean and Enum types).
private Long empId;
with
<h:inputText value="#{bean.empId}" />
You'd like to use required attribute to validate required input.
<h:inputText value="#{bean.empId}" required="true" />
Any conversion or validation error message can be shown using <h:message>.
<h:inputText id="empId" value="#{bean.empId}" required="true" />
<h:message for="empId" />
You can if necessary change the conversion and required message as follows:
<h:inputText id="empId" value="#{bean.empId}" required="true"
requiredMessage="Please enter employee ID."
converterMessage="Please enter digits only." />
<h:message for="empId" />
This way you don't need to perform any conversion/validation in the bean's action method, which would be the wrong place for it anyway. You should use JSF builtin converters or a custom Converter for conversion and JSF builtin validators or a custom Validator for validation. The backing bean property should hold the right type already and the backing bean action method should not do any conversion/validation.
I only wonder if that DAO method call to check the column can't better be handled by a custom Validator, but that depends all on the concrete functional requirement which is unclear from the question.

Resources