views:

222

answers:

1

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?

+1  A: 

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.

BalusC
Thanks Balus. I like your idea for option 1, potentially I should be able to do the opposite then when data is loaded by in phase listener and reinitialise EditableValueHolders back.Regarding your second suggestion, I can't find any unserialize() function in jQuery, how would you load the draft data?
Swiety
By setting the managed bean properties in server side accordingly.
BalusC