禁用立即操作的验证

时间:2014-01-28 15:13:34

标签: validation jsf primefaces

我有一个带有p:commanButton的复杂页面,其中包含actionListener和immediate="true"

单击此commandButton后,我需要处理单个inputField(从而跳过表单的其余部分)。问题是,inputField有一个验证器,我只想在整页提交中使用它。

<p:inputText id="#{cc.attr.id2}_input" value="#{myBB.value}" 
                 immediate="true">
    <f:validateLength minimum="4"/>
</p:inputText>

<p:commandButton id="#{cc.attr.id2}_search" immediate="true" 
     process="#{cc.attr.id2}_input @this"
     actionListener="#{myBB.listener}">
</p:commandButton>

当我使用inputText中的3个字母执行此操作时,由于验证失败,myBB.value未更新。所以我想禁用inputField的验证器,以便commandButton立即处理。但我不知道怎么做。

我知道我可以从ExternalContext获得价值,但这对我来说似乎是一个非常hacky的解决方案(在我的情况下甚至不适用,因为它在复合组件内部,我无法知道textField的clientId。) 我也知道disabled标记的validator属性,但我不知道如何在这种情况下使用它。

编辑:我已经改变了一些代码,因为我使用的ID实际上并不像我先说的那么简单,也不允许我使用简单的建议解决方案。

我使用Mojarra 2.2.4和Primefaces 4.0

1 个答案:

答案 0 :(得分:3)

首先,您没有遇到immediate的问题,而是使用<f:validateLength>验证程序。

也就是说,为了重新解释您的问题,您希望在单击特定按钮的情况下跳过给定组件的验证。

根据您是否使用Mojarra 2.1.18+,有两种解决方案。第一个非常简单:使用<f:validateLength>的禁用属性,而另一个考虑issue 1492。正如我们现在已经超越上述版本的Mojarra,我将发布第一个更简单的解决方案,否则,滚动浏览BalusC对Why does f:validateDoubleRange only work for @SessionScoped?Disabled attribute of <f:validateLength> does not evaluate request parameters的优秀答案。

所以,解决方案如下:

<h:form id="formId">
    <p:inputText id="inputId" value="#{myBB.value}">
        <f:validateLength minimum="4" disabled=#{not empty param['formId:buttonId']}" />
    </p:inputText>
    <p:commandButton id="button" process="@this inputId" actionListener="#{myBB.listener}" />
</h:form>

作为旁注,您可以看到我根本没有使用immediate属性,因为我认为您滥用它来执行给定任务。随着AJAX的兴起,特别是在基于JSF的应用程序中,您现在可以通过指定process<p:commandButton>的{​​{1}}属性而不是之前使用的优先级来轻松地对输入元素验证的子集进行分组验证尤其是在同步请求中。只有那些提供了id的组件才会在服务器上处理,所有其他组件将被省略为prom处理生命周期。另请注意,<p:ajax>也必须执行与按钮itseld相关联的操作。

关于process="@this ..."的正确使用,我强烈建议您参考BalusC的经典:Debug JSF lifecycle博客文章,检查您是否正确使用过它。