PrimeFaces password validation - 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

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

Group elements for a single ajax call in event="change"

I have a form with inputs to fill customer data with name surname and id
name surname lastName
[ ] [ ] [ ]
id other fields
[ ] [ ]
Inputs are defined as usually:
<p:inputText id="name" required="true" value="#{contactForm.name}" label="Name" styleClass="form-control">
<p:clientValidator/>
</p:inputText>
<p:message for="name" />
When id field is filled I make an ajax call to see if data corresponds with a customer in this way:
<p:outputLabel for="ID" value="ID" />
<p:inputText id="ID" required="true" value="ID" label="ID" styleClass="form-control">
<p:ajax
event="change"
listener="#contactController.identifyCustomer(contactForm)}"
process="#this name,surname1,surname2"
update="newCustomerPanel"
/>
<p:clientValidator/>
</p:inputText>
<p:message for="dni" />
In the happy case user introduces all data in a correct way this works nice.
My problem comes when the ajax call is executed with no data retrieved and the user needs to change some of the inputs, if the event needs to be launched user must pass through id input field change data and return which is not the way.
Now is working with workaround: inserting an ajax call to all fields involved. When any input launches event, in server side I check if all data is complete and has changed to call the service that retrieves customer data...
But honestly, this is an ugly solution that wastes lot of calls and does not give a good user experience.
So I was wondering, is there a way group all fields and assign the ajax call and event="change" to this group?
Ajax tag can be used as a wapper for multiple components:
<f:ajax event="change">
<h:input value... />
<h:input value... />
<h:input value... />
</f:ajax>

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?

Custom validator not invoked when fields are empty

I have implemented a custom validator for my screen referring to the example given here.
But in my case, my validator method is not invoked if I don't enter any values in any of the field. So the check for empty fields is never done. The required messages are displayed everytime.
If I removed the required attributes, even in that case the validator is invoked only if the fields have some value in them. How do I get all my validations to be done in the validator class?
My xhtml:
<h:form>
<p:messages id="message" closable="true"/>
<h:panelGrid columns="3" id="changePassPanel">
<h:outputLabel for="pwd0" value="Current password :" />
<p:password id="pwd0" value="#{homeBean.password1}">
<f:validator validatorId="PasswordValidator"></f:validator>
<f:attribute name="pwd1" value="#{pwd1}" />
<f:attribute name="pwd2" value="#{pwd2}" />
</p:password>
<h:outputLabel for="pwd1" value="New password :" />
<p:password id="pwd1" value="#{homeBean.password2}" binding="#{pwd1}"/>
<h:outputLabel for="pwd2" value="Confirm new password :" />
<p:password id="pwd2" binding="#{pwd2}"/>
</h:panelGrid>
<p:commandButton id="saveButton" value="Save" validateClient="true"/>
</h:form>

RichFaces: partial form validation

I have a form containing several fields(name, surname, etc) and a datatable. Datatable is dedicated to store addresses into the backing bean. A person can have more than one address so I add a button as follows:
<a4j:commandButton action="#{bean.addAddressRow}" value="Add address" reRender="addresses" />
where "addresses" is the id of my datatable. I use a4j because there's no need to refresh the page.z
What I want to do is to skip the validation of the entire form except the address fields when this button is pressed. So a user can add one more address if all the previous addresses are correctly filled. The other fields should not be validated.
Is it possible to do?
Wrap your address table and the commandButton with <a4j:region> tags and set the attribute renderRegionOnly to true. Look at following example. Here only the last two text boxes (txt2 and txt3) are validated when you press the first button. If you press the second button all three text boxes are validated.
<h:form>
<h:inputText required="true" id="txt1"/>
<rich:message for="txt1" style="color:red"/>
<a4j:region renderRegionOnly="true">
<h:inputText required="true" id="txt2"/>
<rich:message for="txt2" style="color:red"/>
<h:inputText required="true" id="txt3"/>
<rich:message for="txt3" style="color:red"/>
<a4j:commandButton value="Ok1" />
</a4j:region>
<a4j:commandButton value="Ok2" />
</h:form>

Resources