JSF跳过Required-Validation而不是immediate = true

时间:2013-01-15 10:24:06

标签: validation jsf lifecycle immediate-attribute

我有多种形式,我有必填字段和可选字段。

提交这样的表单,我需要对要执行的required-attribute进行验证,这样可以正常工作。 要取消此类表单,我使用immediate="true"上的属性p:commandbutton,这会使其在应用请求值期间执行操作在这里:How to skip validation when a specific button is clicked?

但是,对于大型表单,我想为用户提供一个保存按钮,以便他可以稍后继续。

为了保存当前状态,我还想忽略required-attribute的验证。但是,使用immediate="true"不起作用,因为我的save方法简单保存,因为JSF生命周期永远不会命中“UpdateModelValues”-Phase。 (根据http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html

那么,如何绕过所需的检查但不会跳过生命周期的一半?

6 个答案:

答案 0 :(得分:64)

每个Button在Param-List中创建一个条目,只要它是表单的成员即可。 所以我简单地检查了该条目是否存在于“required”参数:

<h:form id="form" prependId="true">
...
<p:inputText id="someId"
    required="#{param['form:save']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>

当我点击“提交”时,param['form:save']NULL,然后将表达式转为true,以便执行验证。

当我点击“保存”时,param['form:save']NOT NULL(但为空!),这会解析为false,因此会忽略验证。 (或者让我们说JSF认为它不是必需的字段,因为表达式被评估为false

答案 1 :(得分:5)

如果要在单击按钮时跳过验证,请轻松地将参数添加到要跳过的按钮。例如:

<p:commandButton value="button1" action="#{bean.action()}" >
   <f:param name="skipValidator" value="true"/>
</p:commandButton>

然后在验证器中你可以读取这个参数,如果是,则跳过它:

@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{

  public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException { 
    if(!continueValidation()){
      return;
    }
    // validation process
  }

protected boolean continueValidation() {
    String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
    if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
      return false;
    }
    return true;
  } 
}

答案 2 :(得分:4)

这是一个很好的问题,也是一个非常有用的答案。这种方法为immediate="true"节省了很多麻烦。

我想添加此信息(但暂不予评论)。您的代码示例似乎需要 JSF 2.0 或更高版本(请更正)。如果你像我一样使用JSF 1.1 / 1.2,那么请考虑这些更改/添加:

<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
  • JSF 1.1中没有prependId属性
  • 因此,在参数[...]中,您只能指定按钮ID
  • 您使用的语法="{true and ...}"可能是错误的(没有#)?
  • 正如您从自己的编辑历史中看到的那样,“null或not null”逻辑并不是非常直观:)这就是为什么我偶然发现!empty ...版本的原因。

答案 3 :(得分:1)

其他人提议的替代方法是使用自定义BeanValidator来验证表单,如果说,单击带有id保存的按钮。未隐式定义以执行验证的任何其他按钮将不会验证,只是提交您的数据。找到完整美观的例子here

答案 4 :(得分:0)

在我的情况下,我没有找到params中按钮的clientId,但我发现了这个 请求映射中的param['javax.faces.source'] = buttonClientId。该值将是单击按钮的clientId。

答案 5 :(得分:0)

在这种情况下,我使用skipValidators(假设跳过了所有验证)。来自omnifaces

的代码
<h:form>
  <h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:inputText value="#{item.value}" required="true" />
    </h:column>
  </h:dataTable>
  <h:commandButton value="add new row" action="#{bean.add}">
    <o:skipValidators />
  </h:commandButton>
  <h:commandButton value="save all data" action="#{bean.save}" />
  <h:messages />
</h:form>