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

Swi*_*ety 12 validation jsf

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

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

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

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

但是你看,没有人真的合情合理.这个问题真的没有简单的解决方案吗?

Bal*_*usC 8

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

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

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

$.post('/savedraft', $('#formid').serialize());
Run Code Online (Sandbox Code Playgroud)

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


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