Reputation: 6111
I am new to JSF and going through one JSF application.
I want to validate one Password field for Blank string.
I know instead of doing it in Javascript, I am calling a function for validation.
My need is, if value of the password field is blank then it is validated from validator function till now it is going correctly but after validation when it come =s to UI bav=ck at that time password field should be empty.
If password field is empty(contains spaces only) then i want it to set it as blank or else keep data as it is.
My try till now, JSF view page singin.xhtml
<h:outputText styleClass="outputBox" style="margin: 3px;"
value="Password" />
<h:inputSecret id="password" required="true"
requiredMessage="Please enter your password"
value="#{userActionManager.dto.password}"
validator="#{userActionManager.validateSamePassword}">
<a4j:ajax event="change" execute="@this" bypassUpdates="true" />
</h:inputSecret>
Validator method.
public void validateSamePassword(FacesContext fc, UIComponent component, Object obj) {
System.out.println("UserActionManager.validateSamePassword()");
String confirmPassword = (String)obj;
System.out.println("Password is :" + confirmPassword);
if(confirmPassword!=null && confirmPassword.trim().equals("")) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Password cannot be blank", " detail Passwords do not match!");
// System.out.println(component.getFamily());
// String field1Id = (String) component.getAttributes().get("password");
// Find the actual JSF component for the client ID.
// UIInput textInput = (UIInput) fc.getViewRoot().findComponent("password");
// textInput.setValue("");
dto.setPassword(null);
throw new ValidatorException(message);
}else{
dto.setPassword(confirmPassword);
}
}
I tried option dto.setPassword(null); but when it returns to view, blank spaces in password field is still there and i have to manually remove.
what I am missing?
Upvotes: 1
Views: 3613
Reputation: 1108722
If a component is marked invalid, then it won't redisplay the model value (in your case, the value from the dto
). Instead, it will redisplay its submitted value. You just need to set the submitted value to an empty string.
Replace
dto.setPassword(null);
by
((UIInput) component).setSubmittedValue("");
Upvotes: 1
Reputation: 20691
Within your validator, call resetValue()
on the instance of UIComponent
passed as argument
public void validateSamePassword(FacesContext fc, UIComponent component, Object obj) {
System.out.println("UserActionManager.validateSamePassword()");
String confirmPassword = (String)obj;
System.out.println("Password is :" + confirmPassword);
if(confirmPassword!=null && confirmPassword.trim().equals("")) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Password cannot be blank", " detail Passwords do not match!");
component.resetValue();
throw new ValidatorException(message);
}else{
dto.setPassword(confirmPassword);
}
}
dto.setPassword(null)
will not affect the value in the password box as input components are designed to preserve the values that caused them to fail validation. resetValue()
is a method that will cause the component to reset it's value to an uninitialized state
EDIT: The solution above resets the input value prematurely. Technically, validation doesn't fail until a ValidationException
is thrown. To effectively reset the field:
Define a listener event that will reset the value of the component only after validation fails
public void resetPwd(ComponentSystemEvent evt) throws IOException {
HtmlInputSecret txt = (HtmlInputSecret) evt.getComponent();
if(!txt.isValid()){ //make sure that the validation failed
txt.resetValue();
}
}
Attach the listener event to the postValidate
event listener on the password component. This will ensure that the value is reset only after validation has failed.
<h:inputSecret id="password" required="true"
requiredMessage="Please enter your password"
value="#{userActionManager.dto.password}"
validator="#{userActionManager.validateSamePassword}">
<f:event name="postValidate" listener="#{userActionManager.resetPwd}"/>
<a4j:ajax event="change" execute="@this" bypassUpdates="true" />
</h:inputSecret>
The key here is to reset the value at the right time. Other options for time include the preRenderView
event and postAddToView
event. It's all in the timing
Upvotes: 1