【问题标题】:How to let validation depend on the pressed button?如何让验证取决于按下的按钮?
【发布时间】:2016-10-20 22:34:08
【问题描述】:

我创建了表单,我想在创建新项目时在表上显示以前的现有项目。我想在表格填满时显示匹配的项目。但是,当我尝试在未完成表单的情况下过滤列表时,会出现验证消息并且表格不会更新。

不知道这是否可能,但我想做这样的事情:

<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 很陌生。

【问题讨论】:

  • “不想”........

标签: validation jsf jsf-2 primefaces commandbutton


【解决方案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)作为请求参数发送,您可以在请求参数映射中检查它的存在。

另见:

【讨论】:

  • 能否提供一个更详细的示例来说明save 元素的来源?是豆子吗?和clientId 一个参数?就像我之前说的,我对 Java 和 JSF 很陌生,而且我学习了很多。但是我仍然不知道我是否在问一些太基本的东西。非常感谢您花时间回答。
  • 不,这个例子是原样的。 #{save} 绑定到视图。 clientId 只是它的财产。另见docs.oracle.com/javaee/6/api/javax/faces/component/…。没有必要将它绑定到 bean 属性,除非您想从 bean 内部操作组件。但是如果你不需要,那么就没有必要在 bean 中有一个未使用的属性。另见stackoverflow.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。而且我无法进行过滤。感谢您的快速回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    相关资源
    最近更新 更多