Mittwoch, 13. Juli 2011

Validating Nested Forms in Wicket

Wicket provides a wide range of functionality and automatisms for creating and processing forms and thus makes handling user input very easy at least in most cases. When it comes to nested forms though some things might need some tweaking.

First of I want to say that the wicket documentation provides some very useful information about Nested Forms and Conditional Validation which covers this topic pretty much. But unfortunately one case is not really addressed there which I would like mention here.

I stumbled across this when I created two forms nested within each other where the inner form manipulated the content of the outer one and the outer form submits it's data to the backend while ignoring the inner form. So far no problem, but after adding some validators to the inner form submitting the outer form failed. As can be seen on the page for Nested Forms this is the desired default behavior, a form validates all it's children and thus also it's nested forms. So I had a look at Conditional Validation to see what the recommended way was to change this.

At first I tried to use IFormVisitorParticipant interface to isolate my two forms since this seemed the cleanest solution as the inner form would decide for itself if it wants to be validated or not in the given context. But it did not work for me. The problem was that the inner form did not only have validators assigned to it's components but also to itself and these form level validators were still executed.

So I had to look further. The Form class has a validate method that would be perfect for this purpose if it could be overwritten but for some reason (and I am sure it is a good one) this method is final. Another method that is called during validation of a component hierarchy is the isEnabled method but touching it has a lot of impact on basically all phases of a compoents life cycle and you cannot determine if the method is called during validation or another phase like rendering. And this might cause your component to be disabled or worse.

A suggestion from the wicket user mailing list was to use onFormSubmitted on the outer form to remove the validators from the inner form before submitting it and then adding them again. I did not like this idea since in my opinion it clearly breaks cohesion and the law of demeter.

So I decided to disable default form processing on the outer form and perform the validation of it's child components manually. But this also has the implication that the child components inputs are not put into the forms object model by the framework so you have to do this step yourself too.

All in all this is just minor anoyance but it would be pretty cool if IFormVisitorParticipant could be extended in a later release to completely disable a forms validation without affecting other life cycle phases. But I am not sure yet if this is at all possible. So for now we have to live with this ;-)

Keine Kommentare:

Kommentar veröffentlichen