Cannot validate component with empty value - validation

I've got this .xhtml file for the registration page:
<h:inputSecret id="password"
value="#{registraCliente.password}"
required="true"
binding="#{password}"
requiredMessage="Password obbligatoria"
validatorMessage="Password non valida">
<f:validateRegex pattern="(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,}$/)" />
</h:inputSecret>
<h:message for="password" style="color:red" />
<h:inputSecret id="confermaPassword"
required="true"
value="#{registraCliente.confermaPassword}"
requiredMessage="Devi inserire di nuovo la password">
<f:validator validatorId="passwordValidator" />
<f:attribute name="password" value="#{password}" />
</h:inputSecret>
<h:message for="confermaPassword" style="color:red" />
and I want this: if the two input passwords are different, it shows me an error. But if they're the same, then the registration is allowed.
I've also added a validateRegex tag to check the "strength" of the password, but that's when I got some problems.
When I start the server and fill the form (writing the same password in both input text), it should register but it doesn't, it remains on the same xhtml page.
Eclipse's console gives me this warning:
cannot validate component with empty value: j_id_4:confermaPassword
How it comes?
The passwordValidator (link in the comments below) is a bean that implements Validator, I copied it from a blog post of Balusc, who's a JSF guru I should say :D

Related

JSF backing method and form validation

<h:commandButton value="#{msg.signupbutton}" id="registernewuser"
action="registernewuser" execute="#form" update="reg"
style="color:white;background-image:none;background-color:#69A74E;" />
</h:panelGrid>
<h:outputLabel for="email" value="#{msg.emailLabel}: *" />
<p:inputText id="email" value="#{userBean.emailaddr}"
required="true" label="Email" validatorMessage="Invalid Email"
maxlength="32" match="emailtwo" >
<f:validateRegex
pattern="^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*#[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$"></f:validateRegex>
</p:inputText>
<h:message for="email" style="color:red"/>
<h:outputLabel for="emailtwo"
value="#{msg.confirmemailLabel}: *" />
<p:inputText id="emailtwo" label="Confirm Email"
value="#{userBean.emailTwo}" required="true"
requiredMessage="Email is required" maxlength="32" />
<h:message for="emailtwo" style="color:red"/>
Hi, I have this form where I need to check that the second email inputtext field is the same as that of the first email inputtext field. Kind of like the password match in primefaces.
On the first submission and if there are errors in other inputtext fields such as the username, the validation for the username will be done and the backing method registernewuser will not be run.
If there are no validation errors in other fields but only that emailTwo does not match that of email one, the method registernewuser will be run and the validation error will be shown on the form.
Is there a way to let the registernewuser to be executed even when there are errors in other fields? I have like to show the error message "Confirm email not the same as the first email" during the first form submission.
Primefaces 3.4.2
JSF: 2.1.29

PrimeFaces password validation

I have some trouble understanding this PrimeFaces showcase:
<h:panelGrid columns="2" id="matchGrid" cellpadding="5">
<h:outputLabel for="pwd1" value="Password 1: *" />
<p:password id="pwd1" value="#{passwordView.password5}" match="pwd2" label="Password 1" required="true" />
<h:outputLabel for="pwd2" value="Password 2: *" />
<p:password id="pwd2" value="#{passwordView.password5}" label="Password 2" required="true" />
</h:panelGrid>
In particular, I do not understand, why the value binding of both input fields point to the same property password5.
If I follow this example, but add some validation for password strength
#StrongPassword
private String password5;
I get duplicated validation messages on this constraints (for both fields). This is not the intended behaviour, I'd expect
the content of the first input field to be validated for password strength and
the content of the second input field to be validated for equality with the content of the first field
How to achieve this?
As there doesn't seem to be a need to record the second input in the view bean, I didn't add another property for it and just removed the value binding:
<p:password id="pwd2" label="Password 2" required="true" />
This gives the desired result. The content of the second field is also preserved on validation errors.
The best way to validate two passwords to equals in Primefaces <p:password component is to use attribute match, you could put it to your main input password input form and indicate id of your second checking input form (Id of another password component to match value against - from Primefaces docs).
Let me show you an example:
<h:panelGrid columns="2" id="matchGrid" cellpadding="5">
<p:outputLabel for="usPassword" value="Password:"/>
<p:password id="usPassword" value="#{authBean.password}"
required="true" placeholder="Password"
requiredMessage="Error: enter your password"
match="usPasswordConfirm"/>
<p:outputLabel for="usPasswordConfirm" value="Repeat Password:"/>
<p:password id="usPasswordConfirm" value="#{signupBacking.password}"
required="true" placeholder="Repeat Password"
requiredMessage="Error: repeat your password"/>
</h:panelGrid>
Here I used match="usPasswordConfirm" and the same id value has the second password input form, so Primefaces will check both typed values for a match

Primefaces password match on blur always validation error

Using primefaces password tag, I want to use the match as shown in the show case but with on blur validation, I use the following code:
<h:form id="formulaire">
<p:growl id="growl" showDetail="true" autoUpdate="true" />
...
<p:password id="pwd1" value="#{registrationBean.user.password}"
size="47" label="Password" required="true"
placeholder="Password*" >
<f:validateLength minimum="6" />
<p:ajax event="blur"/>
</p:password>
<br />
<p:password id="pwd2" value="#{registrationBean.user.password}"
size="47" label="Verification" required="true"
placeholder="Verification*" match="pwd1">
<p:ajax event="blur"/>
</p:password>
<br/>
<p:commandButton action="#{registrationBean.register}" value="register"/>
</h:form>
I use the match on the verification, to avoid displaying the error message
before trying to reproduce it.
the problem is that growl always displays the error message.
Even when I put the match on the first field, the growl error keeps showing.
Thank you for your help.
Edit:
The Best solution I managed to get is the following:
<p:password id="pwd1" value="#{registrationBean.password}"
size="47" label="Password" required="true"
placeholder="Password*" match="pwd2">
<f:validateLength minimum="6" />
</p:password>
<br />
<p:password id="pwd2" value="#{registrationBean.password}"
size="47" label="Verification" required="true"
placeholder="Verification*" >
<p:ajax process="pwd1 pwd2" event="blur"/>
</p:password>
the draw back is that there is no ajax verification after password is entered (length...), this is done only once the verification is entered.
(still looking for a better solution)

Validate two components with dynamic id

Here is what I am trying to do:
I have a form with multiple pairs of input fields and a save button.
When the save button is pressed then for each pair of input fields should be validated if they are numbers and if the left value is smaller than the right value.
If not the validation errors will be shown and if it is the case a dialog will pop up to ask for the name under which it should be saved.
Here is what I got so far:
<h:form>
<ui:repeat value="#{myBean.someList}" var="elem">
<h:inputText id="min#{elem.id}" value="#{elem.minimum}" />
<h:inputText id="max#{elem.id}" value="#{elem.maximum}" />
<br />
<h:message for="min#{elem.id}" style="color:red" />
<h:message for="max#{elem.id}" style="color:red" />
</ui:repeat>
<h:commandButton value="save">
<f:ajax execute="#form" render="#form updateValidationFailedFlag"
onevent="
function(ajaxResult){
if(ajaxResult.status=='success' && !globalValidationFailedFlag)
showSaveDialog();
}"
/>
</h:commandButton>
<h:outputScript id="updateValidationFailedFlag">
globalValidationFailedFlag = #{facesContext.validationFailed};
</h:outputScript>
</h:form>
This works but doesn't check if the minimum is smaller then the maximum.
It will validate the input (checks if the input are integer) and shows the save dialog if no validation error occured.
To check if the minimum is smaller then the maximum I tried to follow the tutorial at http://www.mkyong.com/jsf2/multi-components-validator-in-jsf-2-0/
Variant 1 adds a listener after the validation is done and is able to add error messages that are shown in the browser. But that doesn't count as a validation failure and doen't set the facesContext.validationFailed flag.
Variant 2 writes a custom validator for one component and gives the other component as parameter to that validator. That would look something like this:
<f:validator validatorId="myValidator" />
<f:attribute name="maximum" value="#{max#{elem.id}}" />
That is not really valid EL and I don't know how to write it correctly.
What can I do to validate if each of those min-max pairs is valid
You don't need #{elem.id} here. The <ui:repeat> already takes care of that. It would be evaluated to an empty string anyway when JSF needs to set the id attribute.
<ui:repeat value="#{myBean.someList}" var="elem">
<h:inputText id="min" value="#{elem.minimum}" />
<h:inputText id="max" value="#{elem.maximum}" />
<br />
<h:message for="min" style="color:red" />
<h:message for="max" style="color:red" />
</ui:repeat>
As to the validation, just pass the value of the other component along:
<h:inputText id="min" binding="#{min}" value="#{elem.minimum}" />
<h:inputText id="max" value="#{elem.maximum}">
<f:validator validatorId="myValidator" />
<f:attribute name="min" value="#{min.value}" />
</h:inputText>
Note that I moved the validator to the second component. Otherwise it would be still invoked if the second component didn't pass conversion.
If you happen to use JSF utility library OmniFaces, then you could use its <o:validateOrder> instead.
<h:inputText id="min" value="#{elem.minimum}" />
<h:inputText id="max" value="#{elem.maximum}" />
<o:validateOrder components="min max" showMessageFor="min" />
See also:
How to use EL with <ui:repeat var> in id attribute of a JSF component
JSF doesn't support cross-field validation, is there a workaround?

How can I choose where the error message from the validator `required` appear?

How can I choose where the error message from the validator required appear?
The error message is now displayed at the bottom of my page but I want it next to my inputbox.
<p>Firstname: <h:inputText value="#{userBean.firstname}" required="true"/></p>
<p>Lastname: <h:inputText value="#{userBean.lastname}" required="true"/></p>
Those appearing at the bottom are actually unhandled messages which will only appear when the javax.faces.PROJECT_STAGE is been set to Development in web.xml.
You need a <h:message> to declare the location where the message should be shown. Further, you also need a <h:outputLabel> to represent the labels (which has semantic and usability advantages).
Here's the complete set:
<p>
<h:outputLabel for="firstname" value="Firstname:"/>
<h:inputText id="firstname" label="Firstname" value="#{userBean.firstname}" required="true"/>
<h:message for="firstname" />
</p>
<p>
<h:outputLabel for="lastname" value="Lastname:"/>
<h:inputText id="lastname" label="Lastname" value="#{userBean.lastname}" required="true"/>
<h:message for="lastname" />
</p>

Resources