简体   繁体   English

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

[英]JSF skip Required-Validation without immediate=true

I have multiple forms, where I have mandatory fields and optional fields. 我有多种形式,我有必填字段和可选字段。

To submit such a form I require the validation on the required-attribute to be executed, which works fine. 提交这样的表单,我需要对要执行的required属性进行验证,这样可以正常工作。 To cancel such a form I use the attribute immediate="true" on the p:commandbutton , which makes its action happen during the Apply Request Values -Phase as addressed here: How to skip validation when a specific button is clicked? 取消这样的表单,我在p:commandbutton上使用属性immediate="true" ,这使得它的操作发生在Apply Request Values -Phase中,如下所示: 如何在单击特定按钮时跳过验证?

However, for large forms I want to provide the user with a Save-Button, so he can proceed later. 但是,对于大型表单,我想为用户提供一个Save-Button,以便他可以稍后继续。

For just saving the current state I also want to ignore the validation of the required-attribute. 为了保存当前状态,我还想忽略required-attribute的验证。 However, using immediate="true" is not working, because then my save method simple saves nothing, because the JSF lifecycle never hits the "UpdateModelValues"-Phase. 但是,使用immediate="true"是行不通的,因为那时我的save方法没有任何保存,因为JSF生命周期永远不会命中“UpdateModelValues”-Phase。 (Acording to http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html ) (根据http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html

So, how to bypass the required-check but not skip half the lifecycle? 那么,如何绕过所需的检查但不跳过生命周期的一半?

Each Button creates an entry inside the Param-List as long as it's member of the form. 每个Button在Param-List中创建一个条目,只要它是表单的成员。 So I simple applied a check for the presence of that entry to the "required" parameter: 所以我简单地检查了该条目是否存在于“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>

When I click "Submit" the param['form:save'] is NULL , which then turns the expression to true so the validation is executed. 当我单击“提交”时, param['form:save']NULL ,然后将表达式转换为true以便执行验证。

When I click "Save" the param['form:save'] is NOT NULL (but empty!), which resolves to false so the validation is ignored. 当我单击“保存”时, param['form:save']NOT NULL (但为空!),它会解析为false因此忽略验证。 (Or let's say JSF thinks it is not a required field due to the expression beeing evaluated to false ) (或者让我们说JSF认为它不是必需字段,因为表达式被评估为false

if you want to skip validation when click on button then easly add parameter to button where you want to skip it. 如果要在单击按钮时跳过验证,请轻松地将参数添加到要跳过的按钮。 Example: 例:

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

Then in validator you can read this parameter and if it is true then skip it: 然后在验证器中,您可以读取此参数,如果为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;
  } 
}

This is an excellent question and a very helpful answer. 这是一个很好的问题,也是一个非常有用的答案。 This approach saves a lot of hassle with immediate="true" . 这种方法通过immediate="true"节省了很多麻烦。

I'd like to add this info (but am not allowed to comment yet). 我想添加此信息(但暂不予评论)。 Your code examples seem to require JSF 2.0 or above (correct me). 您的代码示例似乎需要JSF 2.0或更高版本(请更正)。 If you are like me damned to use JSF 1.1/1.2 then consider these changes/additions: 如果你像我一样使用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>
  • There is no attribute prependId in JSF 1.1 JSF 1.1中没有prependId属性
  • Therefore in the param[...] you must only specify the button id 因此,在参数[...]中,您只能指定按钮ID
  • You are using a syntax ="{true and ...}" that might be a mistake (no # )? 您使用的语法="{true and ...}"可能是一个错误(没有# )?
  • As you can see from your own editing history the "null or not null" logic is not very intuitive :) Thats why I immediately liked the !empty ... version when I stumbled upon it. 正如您从自己的编辑历史中看到的那样,“null或not null”逻辑不是非常直观:)这就是为什么我偶然喜欢!empty ...版本时我偶然发现它。

An alternative to what others proposed is to use a custom BeanValidator that will validate the form if say, clicked the button with id save. 替代其他人提出的是使用自定义BeanValidator来验证表单,如果说,单击带有id的按钮保存。 Any other button not implicitly defined to perform validation will not validate but just submit your data available. 未隐式定义以执行验证的任何其他按钮将不会验证,只是提交您的数据。 Find the full nice and clean example here 这里找到完整美观的例子

In my case I didn't find the clientId of the button in the params but I found this param['javax.faces.source'] = buttonClientId in the requestmap. 在我的情况下,我没有在params中找到按钮的clientId,但我在requestmap中发现了这个param['javax.faces.source'] = buttonClientId The value will be the clientId of the clicked button. 该值将是单击按钮的clientId。

I use skipValidators for such a case (assuming all validations are skipped). 我在这种情况下使用skipValidators (假设跳过所有验证)。 Code from omnifaces 来自omn​​ifaces的代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM