I took the following BalusC kickoff example and modified it a bit by adding a submit button and additional h:messages and removing the f:ajax
from the h:inputSecret's
(removed the f:ajax
cause for some reason when I leave the first h:inputSecret
it immediately displays "value is required" error for the second h:inputSecret
- but the user haven't got the chance to type it in... ??? <- another future question ?:) )
OK, to make long story short:
I'm trying to figure out how can display the validation errors regarding the both password fields(that the passwords are not equal) in the global h:messages and not in the individual h:message of the password fields
I do want that the required="true" will be displayed in the <h:message
of each field...
But right now the validation message (thrown by my exception) and the required="true" are being displayed in the same place
Here is the code:
<h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
<f:validator validatorId="confirmPasswordValidator" />
<f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
</h:inputSecret>
<h:message id="m_password" for="password" />
<h:outputLabel for="confirm" value="Password (again):" />
<h:inputSecret id="confirm" binding="#{confirmPassword}" required="true">
</h:inputSecret>
<h:message id="m_confirm" for="confirm" />
And additional h:commandButton
with h:messages
below that code :
<h:commandButton value="doSomething" action="#{myBean.myAction}">
<f:ajax execute="password confirm" render="m_password m_confirm"></f:ajax>
</h:commandButton>
<h:messages globalOnly="true" styleClass="validation_value_required"/>
@FacesValidator("confirmPasswordValidator")
public class ConfirmPasswordValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String password = (String) value;
String confirm = (String) component.getAttributes().get("confirm");
if (password == null || confirm == null) {
return; // Just ignore and let required="true" do its job.
}
if (!password.equals(confirm)) {
throw new ValidatorException(new FacesMessage("Passwords are not equal."));
}
}
}
Also
Thanks ahead,
Solution (Thanks to BalusC)
changed
<f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
to
<f:attribute name="confirm" value="#{confirmPassword}" />
and
String confirm = (String) component.getAttributes().get("confirm");
into
UIInput confirmPasswordComponent = (UIInput) component.getAttributes().get("confirm");
String confirm = (String) confirmPasswordComponent.getSubmittedValue();
and
throw new ValidatorException(new FacesMessage("Passwords are not equal."));
into
context.addMessage(null, new FacesMessage("Passwords are not equal."));
context.validationFailed();
((UIInput) component).setValid(false);
confirmPasswordComponent.setValid(false);
return;