JSF如何临时禁用验证器来保存草稿

时间:2010-05-06 12:05:01

标签: jsf validation

我有一个非常复杂的表单,有很多输入和验证器。对于用户来说,完成该操作需要相当长的时间(甚至超过一小时),因此他们希望能够保存草稿数据,即使它违反了未输入必填字段等规则。

我认为这个问题在许多Web应用程序中很常见,但是找不到任何公认的模式应该如何实现。你能告诉我如何实现这个目标吗?

现在我可以看到以下选项:

     
  1. 在“保存草稿”按钮上使用immediate = true不起作用,因为UI数据不会存储在bean上,所以我将无法访问它。从技术上讲,我可以在UI组件树中找到数据,但遍历这似乎不是一个好主意。  
  2.  
  3. 从页面中删除所有字段验证,并在为表单定义的动作侦听器中验证程序数据。再一次,不是一个好主意,形式真的很复杂,有很多字段,所以验证实现这种方式会非常混乱。  
  4.  
  5. 实现我自己的验证器,它将由一些请求属性控制,该属性将被设置为标准表单提交(预期完全验证),并且将被设置为“另存为草稿”提交(当应该跳过验证时)。同样,不是一个好的解决方案,我需要为我正在使用的所有验证器提供我自己的包装器。  
  6. 但是你看,没有人真的合情合理。这个问题真的没有简单的解决方案吗?

2 个答案:

答案 0 :(得分:8)

这确实不那么容易。在JSF生命周期中,验证非常紧密。

我个人会选择1.真的,肮脏的工作,但你可以把它藏在一个实用工具类左右。只需从viewroot中获取有问题的<h:form>,递归迭代其子项,在此测试component instanceof EditableValueHolder是否为真,将找到的id-value对存储为Map,最后保留它

作为第四种选择,您可以使用ajaxical powers独立保存所有数据。 jQuery对此很有帮助。

$.post('/savedraft', $('#formid').serialize());

它只需要客户端的Javascript支持。


更新:JSF实用程序库OmniFaces具有<o:ignoreValidationFailed>标记处理程序,用于确切目的。它确实不是一个简单的解决方案,因为它也需要自定义<h:form>。它通过在验证和更新模型值阶段期间提供自定义FacesContext实例来完成其工作,这些阶段在validationFailed()renderResponse()方法中执行NOOP。因此组件仍然无效并且消息仍然附加,但它仍将继续进行更新模型值并调用应用程序阶段。

答案 1 :(得分:1)

我有同样的问题,我不喜欢跳过所有验证的想法。经过深思熟虑后,我最终只想跳过必填字段验证。这背后的逻辑是用户要么完成一个字段正确,要么根本不完成它。这对我来说非常重要,因为一切都在数据库中结束,当然,我不想溢出数据库字段或最终将String值保存到INT数据库字段中例如。

根据我的经验,跳过必填字段可以提供足够的机动余地来保存草稿。为了达到这个目的,我最终编写了一个显示单个警告消息的requiredWarnValidator

public void validate(FacesContext context, UIComponent component, Object value)
    throws ValidatorException {

  if (value == null) {
    FacesMessage message = new FacesMessage();
    message.setSeverity(FacesMessage.SEVERITY_WARN);
    message.setSummary("This field is required.");
    context.addMessage(component.getClientId(), message);
    context.validationFailed();
  }
}

在这个验证器中,我没有抛出ValidatorException(),因为我想通过验证阶段,但我打电话给validationFailed(),因为我想知道是否填写了必填字段。

我在用于保存表单的实体中有一个标记(completed)。保存表单时,我会检查isValidationFailed()

  • 如果true未填写至少一个必填字段:我取消选中标记completed。 (这是草案)
  • 如果false所有表单都已完成:我会检查标记completed。 (这不是草案)

这也让我有一个&#34; Save&#34;按钮而不是两个按钮(&#34;保存&#34;和&#34;保存为草稿&#34;)。

笔记和已知陷阱:

  • 如果要将草稿保存到数据库,则必须确保没有NOT NULL个约束。
  • 使用转换器和验证器时,您必须确保它们可以处理NULL值。
  • 您的字段outputLabel将丢失必填字段星号。