How validate two password fields by f:ajax when losing focus of second field?

ajax, jsf, jsf-2, passwords, validation

Solution

The `<f:ajax>` submits by default only the current component (as in, `execute="@this"`). If you intend to submit another component along it as well, then you'd need to explicitly specifiy its client ID:

<f:ajax ... execute="@this password" />

This way the validators associated with the `password` component will be fired as well.

See also:

- How validate two password fields by ajax? (a closely related question, asked by yourself)

Update: as per the comments, make sure that you've a `<h:head>` in the template, otherwise JSF won't be able to auto-include the necessary `jsf.js` JavaScript file containing the code responsible for `<f:ajax>` magic.

Problem

I used to validate two passwords, checking if they're the same, this way : ``` Password: <h:message id="m_password" for="password" /><br/> <h:inputSecret id="password" value="#{userC.user.password}" maxlength="15" size="15" required="true"> <f:validator validatorId="confirmPasswordValidator" /> <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" /> </h:inputSecret> <br/> Password (yes, again): <h:message id="m_confirm_password" for="confirm_password" /><br/> <h:inputSecret id="confirm_password" binding="#{confirmPassword}" maxlength="15" size="15" required="true"> <f:ajax event="blur" render="m_password m_confirm_password" /> </h:inputSecret> <br/> ``` And in validator : ``` @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(FacesMessage.SEVERITY_ERROR, null, "passwords don't match")); } } } ``` But I would like to do this verification when the second field of the password lose focus, that's why I'm using the `<f:ajax..>` field, but it seems there's something missing here. What could it be ? update ``` <h:form id="change_password_form"> Password: <h:message id="m_password" for="password" /><br/> <h:inputSecret id="password" value="#{userC.user.password}" maxlength="15" size="15" required="true"> <f:validator validatorId="confirmPasswordValidator" /> <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" /> </h:inputSecret> <br/> Password (yes, again): <h:message id="m_confirm_password" for="confirm_password" /><br/> <h:inputSecret id="confirm_password" binding="#{confirmPassword}" maxlength="15" size="15" required="true"> <f:ajax event="blur" execute="@this password" render="m_password m_confirm_password" /> </h:inputSecret> <br/> <h:commandButton id="change_passord" action="#{userC.changePassword}" value="Change Password" /> <h:messages globalOnly="true" escape="false" /> </h:form> ``` update 2 With BalusC suggestion everything went fine, as I had forget to define my `template`: ``` <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <ui:composition template="/resources/jsf/include/default.xhtml"> <ui:define name="content"> <h:form id="change_password_form"> Password: <h:message id="m_password" for="password" /><br/> <h:inputSecret id="password" value="#{userC.user.password}" maxlength="15" size="15" required="true"> <f:validator validatorId="confirmPasswordValidator" /> <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" /> </h:inputSecret> <br/> Password(yes, again): <h:message id="m_confirm_password" for="confirm_password" /><br/> <h:inputSecret id="confirm_password" binding="#{confirmPassword}" maxlength="15" size="15" required="true"> <f:ajax event="blur" execute="@this password" render="m_password m_confirm_password" /> </h:inputSecret> <br/> <h:commandButton id="change_passord" action="#{userC.changePassword}" value="Change password" /> <h:messages globalOnly="true" escape="false" /> </h:form> </ui:define> </ui:composition> </html> ```

Original source

Related problems