Friday, September 14, 2012

Tapestry Fixed Control Name Fixin


Have you ever had a problems with Tapestry5 ValidationTracker service? When after zone update inside a form you are trying to submit this form, validation fails and all specified form values inside updated zone disappear? No? Then try this demo, choose country, then city(name is empty), submit => validation fails, city value is missed.
Lets see what happens inside the box. We have such template:

This template will be rendered as such html markup:

Then we select some value from country select. This triggers zone update. As result we have updated html markup:

As you can see after zone update we have changed control identifiers and names: added _139c3db913f namespace. Lets see what happens after form submit. The process is similar for all tapestry field components. In processSubmission method all such components stores submitted value in ValidationTracker service:

Then before component rendering it restores its value from ValidationTracker:

The thin spot in this mechanism is so that we can store submitted value for changed control name(beforeCitySelect_139c3db913f) and then restore value for original control name(beforeCitySelect). As result we will have empty value from ValidationTracker.
So, what we can do to fix this issue? We can make control names fixed. All fields inherited from AbstractField generate their control names during setup render phase:

As you can see control name is generated from FormSupport service. So we can create fixin that will replace FormSupport service with wrapper that will generate control names as we need:

So, we just need to place this fixin to Zone component and all its controls will have fixed names. And this controls will not miss their values after validation fails:

The only recomendation is to use explicit unique t:id attributes for all this controls to prevent name duplicates. There is also the namespace parameter that will be added to all generated control names inside zone.

And as usually:
Live demo
Source code

No comments:

Post a Comment