我曾经验证过两个密码,通过这种方式检查它们是否相同:
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/>
在验证器中:
@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"));
}
}
}
但是,当密码的第二个字段失去焦点时,我想进行此验证,这就是我使用<f:ajax..>
字段的原因,但似乎这里缺少一些东西。
它可能是什么?
更新
<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>
更新2
有了BalusC的建议,一切都很顺利,因为我忘了定义我的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>
答案 0 :(得分:4)
<f:ajax>
默认情况下仅提交当前组件(如execute="@this"
)。如果您打算沿着它提交另一个组件,那么您需要明确指定其客户端ID:
<f:ajax ... execute="@this password" />
这样,与password
组件关联的验证器也将被触发。
更新:根据评论,确保您在模板中有<h:head>
,否则JSF将无法自动包含必要的jsf.js
} JavaScript文件,包含负责<f:ajax>
magic的代码。