Bean validation using a custom #RequiredWhen validator and required field decorator in JSF - jsf

I have defined a custom jsr-303-Validator called #RequiredWhen which is like #NotNull but depending on some condition.
In JSF, whenever I annotate a managed bean property with #NotNull a component like PrimeFaces <p:outputLabel for="that property">, recognizes the property as required and marks it with an asterisk. Is it possible to implement or configure my custom Validator such that the asterisk is shown as well, if the condition in the #RequiredWhen-annotation becomes true? Thanks a lot.
I'm using,
Java EE 6
GlassFish 3.1.2
Mojarra 2.1.29
PrimeFaces 5.2

As far as I can see by now the answer is no: it's not possible to show the asterix by configuring or implementing the custom validator. Looking at the sources of primefaces the check for #NotNull is hardcoded and there is no kind of callback to check for other annotations.
As a first workaround we added a new bean that checks an input field for our custom annotations, eg
<p:inputText id="test" value="#{uiController.data}"
required="#{ContextValidatorDelegate.isRequired('data')}"/>
But after some closer look we removed that delegate. The condition in our custom validator is dependend on properties that the user can modify in the same dialog than the property that is validated. So our validator really is some class level validator. And thus we cannot use the required-attribute, which is processed in validation phase. We need the complete user-input in our model bean. Only after the update model phase a class level validation is meaningful.

Related

PrimeFaces - Set a JSF component as mandatory

I am using PrimeFaces and JSF - I need to be able to set a component on the page as mandatory in response to an AJAX event. Is the best way to accomplish this using the following code or is there also a way to accomplish it using JQuery ?
Thanks
UIInput componentToChange = (UIInput) facesContext.getViewRoot().findComponent("ComponentId");
componentToChange.setRequired(true);
Thanks
Just set the component's required attribute with the desired EL expression.
E.g.
<h:inputText ... required="#{bean.required}" />
There are even EL ways without needing an additional bean property, but it's impossible to propose one based on the sparse information provided so far.
Use findComponent() with care. Think twice if it really can't be done just in the view (XHTML) side.

UIComponent#getValue() obtained via binding is not available in validator of another component

I'm trying to figure out why an f:attribute tag's value isn't passed when attached to h:inputSecret tag. I'm quite new to jsf, but as far as I know attributes can be attached to any kind of component. Here is the code:
<h:inputSecret id="passw" value="#{advertAdder.userPass}"
required="true" validator="#{advertAdder.validatePasswords}">
<f:attribute name="confirmedPass" value="#{advertAdder.passConfirmator.value}"/>
</h:inputSecret>
<h:inputSecret id="passwConfirm" required="true"
binding="#{advertAdder.passConfirmator}"/>
and the method that wants to acces this attribute:
public void validatePasswords(FacesContext context, UIComponent component, Object value)
{
if (!value.equals(component.getAttributes().get("confirmedPass")))
{
FacesMessage mess = new FacesMessage("Password and it's confirmation are not the same!");
context.addMessage(component.getClientId(context), mess);
((UIInput) component).setValid(false);
}
}
In above code component.getAttributes() always returns map with only two attributes:
javax.faces.component.VIEW_LOCATION_KEY and com.sun.faces.facelets.MARK_ID.
I've added attribute tag to a h:commandButton to check it, and then everything was fine. Am I missing something or it's not possible to add an attribute to non-action tag?
I'm using Mojarra 2.0.2 and Glassfish 3.0.1.
Thanks in advance.
Input components are processed in the order as they appear in the component tree. The UIInput#getValue() is only available when the component is already been processed. Otherwise you need to use UIInput#getSubmittedValue() instead.
<f:attribute name="confirmedPass" value="#{advertAdder.passConfirmator.submittedValue}"/>
Note that this gives you the unconverted and unvalidated value back. It would make somewhat more sense to put the validator on the confirm password field instead and pass the value of the first password field along. See also JSF Validator compare to Strings for Equality and JSF doesn't support cross-field validation, is there a workaround?
Alternatively, you can also try out the OmniFaces <o:validateEqual> component. You can find a concrete example in this article.
Unrelated to the concrete problem, it's unnecessary to bind the component to the bean this way. Replace all occurrences of #{advertAdder.passConfirmator} by #{passConfirmator}. Keep the controller free of properties which are never internally used.

bean and jsf validation annotation inisde managed bean vs entity bean

I'm new in JSF and not sure about a few fundamental issues.
I found i few ways for defining validation for my input fields, but i'm not sure which is the right way to do it.
I'm using bean validation and jsf validation by using ExtVal.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
This question leads me to a more basic one , that I still don't really understand -
I have an entity bean with fields and their setters and getters, also I have a managed bean and a xhtml file with a form that displays the fileds inside inputs.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ?
again what is the diffrence for each approch?
Thank's In Advance.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
Depends on the concrete functional requirement. Key point is: how reuseable should the validation be? If configured at entity level, it's reuseable for all frameworks other than JSF. If configured at JSF level, it's not reuseable for frameworks other than JSF which happen to use the same entity.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ? again what is the diffrence for each approch?
You should not duplicate/expand the data model in the controller. This makes no sense. This is not DRY and is thus only maintenance headache.

JSF Required=Yes not working inside a datatable?

I searched everywhere but could not find a solution to this. I am trying to used
required=yes to validate whether a value is present or not. I am using it inside inputtext.
The problem is it does not work inside a datatable. If I put the text box outside the datatable it works. I am using JSF 1.7 so I don't have the validateRequired tag from JSF 2.0.
I even used a validator class but it is still not working. Does anyone know why does required=yes or validator='validationClass' inside a inputtext inside a datatable is not working.
I appreciate the help.
Thanks.
First of all, the proper attribute values of the required attribute are the boolean values true or false, not a string value of Yes. It's an attribute which accepts a boolean expression.
The following are proper usage examples:
<h:inputText required="true" />
<h:inputText required="#{bean.booleanValue}" />
<h:inputText required="#{bean.stringValue == 'Yes'}" />
As to the problem that it doesn't work inside a <h:dataTable>, that can happen when the datamodel is not been preserved properly (the datamodel is whatever the table retrieves in its value attribute). That can in turn happen when the managed bean is request scoped and doesn't prepare the datamodel during its (post)construction which causes that the datamodel is null or empty while JSF is about to gather, convert and validate the submitted values.
You need to ensure that the datamodel is exactly the same during the apply request values phase of the form submit request as it was during the render response phase of the initial request to display the form with the table. An easy quick test is to put the bean in the session scope. If that fixes the problem, then you definitely need to rewrite the datamodel preserving logic. You could also use Tomahawk's <t:saveState> or <t:dataTable preserveDataModel="true"> to store the datamodel in the view scope (like as JSF2's new view scope is doing).
Finally, JSF 1.7 doesn't exist. Perhaps you mean JSF 1.2?

Bypass bean validation in JSF2?

I'm wondering if it's possible to bypass bean validators for certain actions in JSF2.
I've generated entities from my DB schema using NetBeans 7, which include validation attributes.
In my JSF application I have a search screen who's backing bean uses an instance of an entity to hold the user's query parameters. I then use reflection on the entity instance to generate a dynamic query to perform the user's search. Once the user performs the search they can select an item and go off to an edit page where I'd like the validation enforced.
My problem is that on the search screen, bean validation on my entity is enforced. So if my entity has 3 required fields, and the user searches on only 1 of the 3, I get two "field is required" error messages.
I know I could get around this by creating a new class for my search backing bean that doesn't have validation annotations on it, but that doesn't seem like an ideal solution to me: I'd end up with two essentially identical classes, just with different annotations.
You could add f:validateBean with disabled="true" to your first form where you don't want them validated and then not include it on the view where you do:
<h:inputText value="#{entity.property}">
<f:validateBean disabled="#{true}"/>
</h:inputText>
for me in icefaces didnt work like that: i had to :
<f:validateBean disabled="true" >
<ice:outputText value="#{messages['busqueda.bodega.tabla.datos.etiqueta.nombre']}"/> <ice:inputText" value="#busquedaBodegaBean.busquedaBodegaBB. bodegaCriterio.nombre}">
</ice:inputText>
</f:validateBean>

Resources