如何让验证取决于按下的按钮?

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 输入字段进行过滤。 &lt;p:commandButton&gt; 默认发送一个 ajax 请求并有一个 process 属性,您可以在其中指定您希望在提交期间处理哪些组件。在您的特定情况下,您应该处理name 输入字段和当前按钮(以便调用其操作)。

<p:commandButton process="@this name" ... />

process 属性可以采用空格分隔的组件(相对)客户端 ID 集合,其中 @this 指的是当前组件。在&lt;p:commandButton&gt;@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 答案(非常有用且完整)之外,我想补充一点,当您使用 &lt;h:commandButton /&gt; 时,它将验证(必需的、自定义验证)命令按钮所在的 &lt;h:form /&gt; 中的所有字段,因此,当您需要使用多个命令按钮时,您可以考虑对不同的职责使用不同的&lt;h:form /&gt; 以避免在命令按钮的提交操作中出现意外行为是一种很好的做法。 BalusC 的回答很好地解释了这一点:Multiple h:form in a JSF Page

如果您的表单有验证并且您没有更新 &lt;h:form /&gt; 或者您没有显示消息,您可能会因为认为 &lt;h:commandButton /&gt; 没有触发您的操作而头疼,但很可能是验证问题没有已显示。

【讨论】:

【参考方案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。而且我无法进行过滤。感谢您的快速答复。

以上是关于如何让验证取决于按下的按钮?的主要内容,如果未能解决你的问题,请参考以下文章

根据您按下的按钮将信息发送到不同页面的表单

按钮停止上的按下(波纹)动画

有啥办法可以抓住我按下的按钮?

突出显示被按下的按钮并取消突出显示未按下的按钮 SWIFT

按下和未按下的 UIButton 图像

如何根据按下的按钮取消隐藏标记的详细信息披露按钮