Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF how to temporary disable validators to save draft

Tags:

validation

jsf

I have a pretty complex form with lots of inputs and validators. For the user it takes pretty long time (even over an hour) to complete that, so they would like to be able to save the draft data, even if it violates rules like mandatory fields being not typed in.

I believe this problem is common to many web applications, but can't find any well recognised pattern how this should be implemented. Can you please advise how to achieve that?

For now I can see the following options:

  1. use of immediate=true on "Save draft" button doesn't work, as the UI data would not be stored on the bean, so I wouldn't be able to access it. Technically I could find the data in UI component tree, but traversing that doesn't seem to be a good idea.
  2. remove all the fields validation from the page and validate the data programmaticaly in the action listener defined for the form. Again, not a good idea, form is really complex, there are plenty of fields so validation implemented this way would be very messy.
  3. implement my own validators, that would be controlled by some request attribute, which would be set for standard form submission (with full validation expected) and would be unset for "save as draft" submission (when validation should be skipped). Again, not a good solution, I would need to provide my own wrappers for all validators I am using.

But as you see no one is really reasonable. Is there really no simple solution to the problem?

like image 871
Swiety Avatar asked May 06 '10 12:05

Swiety


1 Answers

It's indeed not that easy. Validation is pretty tight coupled in JSF lifecycle.

I would personally go for option 1. True, dirty work, but you can just hide that away in an utility class or so. Just grab the <h:form> in question from the viewroot, iterate over its children recursively, hereby testing if component instanceof EditableValueHolder is true, store the found id-value pair in sort of Map and finally persist it.

As a fourth alternative, you could save all the data independently using ajaxical powers. jQuery is helpful in this.

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

It only requires Javascript support at the client side.


Update: the JSF utility library OmniFaces has a <o:ignoreValidationFailed> taghandler for the exact purpose. It was indeed not a simple solution as it requires a custom <h:form> as well. It does its job by providing a custom FacesContext instance during the validations and update model values phases which does a NOOP in the validationFailed() and renderResponse() methods. So the components are still invalidated and the messages are still attached, but it would still proceed to the update model values and invoke application phases.

like image 94
BalusC Avatar answered Sep 28 '22 02:09

BalusC