首页 文章

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

提问于
浏览
40

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

要提交这样的表单,我需要对要执行的required属性进行验证,这样可以正常工作 . 要取消这样的表单,我在 p:commandbutton 上使用属性 immediate="true" ,这使得它的动作发生在 Apply Request Values -Phase中,如下所示:How to skip validation when a specific button is clicked?

但是,对于大型表单,我想为用户提供一个Save-Button,以便他可以稍后继续 .

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

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

6 回答

  • 63

    每个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>
    

    当我单击"Submit"时, param['form:save']NULL ,然后将表达式转换为 true ,以便执行验证 .

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

  • 1

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

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

    然后在验证器中,您可以读取此参数,如果为true,则跳过它:

    @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;
      } 
    }
    
  • 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 or not null"逻辑不是很直观:)这就是为什么我偶然发现它时立即喜欢 !empty ... 版本 .

  • 5

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

  • 0

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

  • 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>
    

相关问题