如何让验证取决于按下的按钮?
Posted
技术标签:
【中文标题】如何让验证取决于按下的按钮?【英文标题】:How to let validation depend on the pressed button? 【发布时间】:2012-01-12 07:54:10 【问题描述】:我创建了表单,我想在创建新项目时在表上显示以前的现有项目。我想在表格填满时显示匹配的项目。但是,当我尝试在未完成表单的情况下过滤列表时,会出现验证消息并且表格不会更新。
不知道是否可能,但我想做这样的事情:
<h:form id="form">
<h:outputText value="Name: "/>
<p:inputText value="#itemsBean.name" id="name" required="true"/>
<br/>
<h:outputText value="Description: "/>
<p:inputText value="#itemsBean.description" id="description" required="true"/>
<p:commandButton value="Save" update="form" actionListener="#itemsBean.save"/> //validate and save
<p:commandButton value="Filter" update="form" actionListener="#itemsBean.updateItemsList"/> //don't validate, and update the table.
<p:dataTable id="list" value="#itemsBean.itemsList" var="item">
<p:column>
<h:outputText value="#item.name"/>
</p:column>
<p:column>
<h:outputText value="#item.description"/>
</p:column>
</p:dataTable>
</h:form>
我对 JSF 很陌生。
【问题讨论】:
“不想”........ 【参考方案1】:我了解到您希望根据 name
输入字段进行过滤。 <p:commandButton>
默认发送一个 ajax 请求并有一个 process
属性,您可以在其中指定您希望在提交期间处理哪些组件。在您的特定情况下,您应该仅处理name
输入字段和当前按钮(以便调用其操作)。
<p:commandButton process="@this name" ... />
process
属性可以采用空格分隔的组件(相对)客户端 ID 集合,其中 @this
指的是当前组件。在<p:commandButton>
到@form
的情况下,它默认为@form
(涵盖当前表单的所有输入字段和按下的按钮),这就是为什么它们都在您的初始尝试中得到验证的原因。在上面的示例中,所有其他输入字段都不会被处理(因此也不会被验证)。
但是,如果您打算在按下相关按钮时跳过 所有 字段的required
验证,以便您最终可以处理不一定需要的多个字段 all 填写,然后您需要将required="true"
设为条件而不是检查按钮是否被按下。例如,让它仅在按下保存按钮时评估true
:
<p:inputText ... required="#not empty param[save.clientId]" />
...
<p:inputText ... required="#not empty param[save.clientId]" />
...
<p:commandButton binding="#save" value="Save" ... />
这样,当按下不同的按钮时,它不会被验证为required="true"
。上面示例中的技巧是按下按钮的名称(本质上是客户端 ID)作为请求参数发送,您可以在请求参数映射中检查它的存在。
另见:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes【讨论】:
能否提供一个更详细的示例来说明save
元素的来源?是豆子吗?和clientId
一个参数?就像我之前说的,我对 Java 和 JSF 很陌生,而且我学习了很多。但是我仍然不知道我是否在问一些太基本的东西。非常感谢您花时间回答。
不,这个例子是原样的。 #save
绑定到视图。 clientId
只是它的财产。另见docs.oracle.com/javaee/6/api/javax/faces/component/…。没有必要将它绑定到 bean 属性,除非您想从 bean 内部操作组件。但是如果你不需要,那么就没有必要在 bean 中有一个未使用的属性。另见***.com/questions/8168302/…
哇,这背后有很多我不知道的事情......感谢您的回复,它指出了我需要知道的内容。
这个解决方案是否适用于更复杂的验证器,例如f:validateLength
?是否可以在页面生命周期内应用几次?
为什么我们不能像我们习惯的那样在 PrimeFaces 中使用经典的立即属性?【参考方案2】:
除了 BalusC 答案(非常有用且完整)之外,我想补充一点,当您使用 <h:commandButton />
时,它将验证(必需的、自定义验证)命令按钮所在的 <h:form />
中的所有字段,因此,当您需要使用多个命令按钮时,您可以考虑对不同的职责使用不同的<h:form />
以避免在命令按钮的提交操作中出现意外行为是一种很好的做法。
BalusC 的回答很好地解释了这一点:Multiple h:form in a JSF Page
如果您的表单有验证并且您没有更新 <h:form />
或者您没有显示消息,您可能会因为认为 <h:commandButton />
没有触发您的操作而头疼,但很可能是验证问题没有已显示。
【讨论】:
【参考方案3】:我已经用非 ajax 提交对此进行了测试:
<p:inputText ... required="#not empty param.includeInSave1" />
...
<p:inputText ... required="true" />
...
<p:commandButton value="Save1" ajax="false">
<f:param name="includeInSave1" value="true" />
</p:commandButton>
<p:commandButton value="Save2" ajax="false" />
第一个输入仅在 Save1 按钮提交时才需要验证。
【讨论】:
这个可以绕过。您最好检查 JSF 视图状态中存在的内容,而不是任意且完全由客户端控制的请求参数。查看当前接受的答案。【参考方案4】:像这样更改您的过滤器命令按钮以忽略验证:
<p:commandButton value="Filter" update="list" actionListener="#itemsBean.updateItemsList" process="@this"/>
编辑:
关于SO的相关帖子,我想这也能解决你的问题
JSF 2.0: How to skip JSR-303 bean validation?
【讨论】:
这可以绕过验证,但表单值以 null 形式到达 itemsBean。而且我无法进行过滤。感谢您的快速答复。以上是关于如何让验证取决于按下的按钮?的主要内容,如果未能解决你的问题,请参考以下文章