我有一个非常复杂的表单,有很多输入和验证器。对于用户来说,完成该操作需要相当长的时间(甚至超过一小时),因此他们希望能够保存草稿数据,即使它违反了未输入必填字段等规则。
我认为这个问题在许多Web应用程序中很常见,但是找不到任何公认的模式应该如何实现。你能告诉我如何实现这个目标吗?
现在我可以看到以下选项:
但是你看,没有人真的合情合理。这个问题真的没有简单的解决方案吗?
答案 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
将丢失必填字段星号。