如何通过ajax验证两个密码字段?

Posted

技术标签:

【中文标题】如何通过ajax验证两个密码字段?【英文标题】:How validate two password fields by ajax? 【发布时间】:2011-11-21 08:07:42 【问题描述】:

我正在尝试使用 JSF 验证两个密码字段,但到目前为止效果不佳,我在 google 上搜索它,但所有内容都是关于 JSF 1.2 的,而且相当混乱,我使用的是 JSF 2.0。

这就是我目前正在做的事情:

        <h:outputLabel for="password" value="Password:" />
        <h:inputSecret id="password"  value="#register.user.password"  >  
            <f:ajax    event="blur"   listener="#register.validatePassword" render="m_password" />
        </h:inputSecret>
        <rich:message id="m_password" for="password"/>

        <h:outputLabel for="password_2" value="Password (again):" />
        <h:inputSecret id="password_2"  value="#register.user.password_2"  >  
            <f:ajax    event="blur"     listener="#register.validatePassword" />
        </h:inputSecret>

这就是我的控制器:

public void validatePassword() 
    FacesMessage message;

    if (!user.getPassword().equals(user.getPassword_2()) )
        message = new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "different password");
    else
        message = new FacesMessage(FacesMessage.SEVERITY_INFO, null, "ok");
    

    FacesContext.getCurrentInstance().addMessage("form:password", message);

有什么想法吗?

【问题讨论】:

你是什么意思它工作但不太好?慢吗?不确定我是否了解您想要更改的内容以及原因。 嗨@jdias,我的意思是没有按预期的方式工作。谢谢,这可能有点令人困惑。 【参考方案1】:

您可以使用Primefaces p:password 标签。请看演示example。它有 ma​​tch 属性,应该是确认密码的 id。

<p:panel header="Match Mode">  
    <p:messages id="messages" showDetail="true" autoUpdate="true"/>  

    <h:panelGrid columns="2" id="matchGrid">                     
                <h:outputLabel for="pass" value="Password " />  
                <p:password id="pass" value="#passwordBean.password" match="confirmPass"   required="true"/>  

                <h:outputLabel for="confirmPass" value="Confirm Password " />  
                <p:password id="confirmPass" value="#passwordBean.confirmPassword" required="true"/>  
    </h:panelGrid>  

    <p:commandButton id="saveButton" update="matchGrid" value="Save" />  
</p:panel>

【讨论】:

【参考方案2】:

首先,使用 real Validator 来验证输入。不要在动作事件方法中这样做。

至于您的具体问题,您只需在&lt;f:ajax&gt;execute 属性中指定both 字段,即默认为仅当前组件。如果您将验证器附加到第一个输入并将第二个输入的值作为&lt;f:attribute&gt; 发送,那么您将能够在验证器中获取它。您可以使用binding 属性将组件绑定到视图。这样您就可以通过UIInput#getSubmittedValue() 传递其提交的值。

这是一个启动示例:

<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" />
    <f:ajax event="blur" execute="password confirm" render="m_password" />
</h:inputSecret>
<h:message id="m_password" for="password" />

<h:outputLabel for="confirm" value="Password (again):" />
<h:inputSecret id="confirm" binding="#confirmPassword" required="true">
    <f:ajax event="blur" execute="password confirm" render="m_password m_confirm" />
</h:inputSecret>
<h:message id="m_confirm" for="confirm" />

(请注意,我在两个组件中都添加了required="true",并且还请注意,您不一定需要将确认密码组件值绑定到托管 bean 属性,反正在那里毫无价值)

使用此验证器

@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."));
        
    


【讨论】:

绑定="#confirmPassword" 中的confirmPassword 是什么? @Jsword:它将通过给定的标识符将组件绑定到视图,以便视图中其他位置的#confirmPassword 可以使用它(例如在第一个字段的&lt;f:attribute&gt; 中,以便它可以在验证器中获取)。 我现在明白了'绑定'BalusC的功能,谢谢老兄的帮助。 不客气。顺便说一句,您也可以将其绑定到 bean 属性。然后它将是一个UIInput 属性。但在这种情况下这不是必需的(它会破坏 viewscoped bean)。【参考方案3】:

使用 seam 2,您拥有组件 &lt;s:validateEquality&gt;,您无需编写代码。对于 JSF2,您拥有 Seam 3 模块,特别是 Faces module 和跨字段表单验证。一个例子:

首先你必须使用 s:validateForm 标签:

<h:form id="passwordForm">
    <h:inputSecret id="newPassword"
        required="true"
        redisplay="true"
        value="#passwordController.newPassword">
    </h:inputSecret>            
    <h:inputSecret id="confirmationPassword"
        value="#passwordController.confirmPassword"
        required="true"
        redisplay="true">
    </h:inputSecret>
    <h:commandButton id="submit" value="Submit" action="#passwordController.submitPassword" />
    <s:validateForm validatorId="passwordValidator" />
</h:form>

上面密码表单对应的验证器如下所示:

@FacesValidator("PasswordValidator")
public class PasswordValidator implements Validator

   @Inject
   @InputField
   private String newPassword;

   @Inject
   @InputField
   private String confirmPassword;

   @Override
   public void validate(final FacesContext context, final UIComponent comp, final Object values) throws ValidatorException
   
      if (!confirmPassword.equals(newPassword))
      
         throw new ValidatorException(new FacesMessage("Passwords do not match!"));
      
   

【讨论】:

我在纯 JSF2 中寻找类似的解决方案,但找不到。你知道这是否存在于 JSF2 中吗?尤其是@InputField 注解似乎很有用。

以上是关于如何通过ajax验证两个密码字段?的主要内容,如果未能解决你的问题,请参考以下文章

如果表单未通过验证,密码字段是不是应保留其值?

如何验证ajax表单?

如果托管bean没有更新,如何在事件onblur上使用ajax验证字段[重复]

我有一个密码和一个确认密码字段,我已经使用 laravel 对其进行了验证,但即使两个字段的密码相同,它也显示不匹配?

如何使输入文本字段用*替换任何字符? [复制]

通过 AJAX 验证 Laravel 表单中的文件输入