JSF 跳过没有立即=真的必需验证

Posted

技术标签:

【中文标题】JSF 跳过没有立即=真的必需验证【英文标题】:JSF skip Required-Validation without immediate=true 【发布时间】:2012-12-29 10:13:39 【问题描述】:

我有多个表单,其中有必填字段和可选字段。

提交这样的表单,我需要对要执行的 required-attribute 进行验证,这很好。 要取消这样的表单,我在p:commandbutton 上使用属性immediate="true",它会在Apply Request Values 阶段执行操作,如下所述:@987654321 @

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

为了只保存当前状态,我还想忽略所需属性的验证。但是,使用immediate="true" 不起作用,因为那时我的简单保存方法什么也没有保存,因为 JSF 生命周期从未达到“UpdateModelValues”阶段。 (根据http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html

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

【问题讨论】:

鉴于答案,这在技术上是 How to let validation depend on the pressed button? 的欺骗。 @BalusC 你是对的,但另一个问题是关于一个确切的“技术”细节。这个是我在对所有 JSF 措辞不太熟悉时创建的(我今天稍微更正了一点)——因此它与相应的谷歌搜索完全匹配,初学者可能会提交: google.de/…(不过都是排名靠前的) 【参考方案1】:

我在这种情况下使用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>

【讨论】:

【参考方案2】:

其他人建议的替代方法是使用自定义BeanValidator,如果说单击带有 id 保存的按钮,它将验证表单。任何其他未隐式定义为执行验证的按钮都不会验证,而只是提交可用的数据。找到完整的干净示例here

【讨论】:

【参考方案3】:

只要是表单的成员,每个按钮都会在 Param-List 中创建一个条目。 所以我简单地对“必需”参数应用了该条目是否存在的检查:

<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 认为它不是必填字段,因为表达式 beeing 评估为false

【讨论】:

附注:true and 显然在这里不需要;) @BalusC 我正在使用 Primefaces。不确定,如果有相等的东西。 (现在还没找到) 干得好!极好的。经过3个小时的疯狂,我找到了你的答案。超级酷! 我不认为这是一个很好的用户体验,因为必填字段上的 * 只会在用户单击提交或取消时显示。有没有其他方法可以做到这一点,以便始终显示所需的 *? @Erick 只需生成带有标签的*,它确实包含“常规”所需条件。【参考方案4】:

如果您想在单击按钮时跳过验证,则可以轻松地将参数添加到要跳过它的按钮。示例:

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

【讨论】:

这种方法不会跳过标准生命周期更新模型值,而是跳过 FacesValidator。对像“清洁”按钮很有用。 Tnks 人。【参考方案5】:

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

【讨论】:

【参考方案6】:

这是一个很好的问题,也是一个非常有用的答案。这种方法为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 属性 因此在 param[...] 中您必须只指定按钮 ID 您使用的语法="true and ..." 可能有误(不是#)? 从您自己的编辑历史中可以看出,“null or not null”逻辑不是很直观 :) 这就是为什么我在偶然发现 !empty ... 版本时立即喜欢它的原因。

【讨论】:

true and ... 缺少“#”,这是正确的。真实的也已过时。它在“那里”,因为我们正在自动生成所有表单(在设计时),并且可以选择定义是否需要某些东西。然后,如果表单允许“保存”,我们简单地附加参数检查。而且因为您是对的 - 空值不是很直观,我们决定将“原始”值(真或假)与检查一起保留以提高可读性。 JSF 1.1 默认预置表单的客户端 ID。所以你仍然应该使用form:save。我不确定为什么 dognose 明确声明 prependId="true",因为这已经是默认值了。 @BalusC 我试过了,但它对我不起作用。如果我使用required="#!empty param['save']",则在发布半填表格时会出现预期的验证错误。如果我改用 required="#!empty param['form:save']",则不会发生验证 - 我会收到很多数据库错误;)。 对,您使用的是纯 HTML &lt;form&gt; 而不是 JSF &lt;h:form&gt; 其实我没有。我使用&lt;h:form&gt;。上面的例子是基于 dognoses 的。

以上是关于JSF 跳过没有立即=真的必需验证的主要内容,如果未能解决你的问题,请参考以下文章

没有指定值时不应该跳过验证吗?

没有指定值时不应该跳过验证吗?

即使没有上传输入文件,Laravel mimes 验证也总是被调用(不使用必需的规则)

JSF / PrimeFaces - 如何显示自定义验证器的消息,但不显示同一组件上的必需验证

必填字段的 JSF 验证

当jsf验证失败时,跳过ajax