Things are coming together faster and faster. Paul Ferraro has checked in his revamp of Tapestry's validation subsystem. It's looking cool, but needs a little tweaking to maximize useability. In the meantime, I've marked ValidField as deprecated ... because Paul's code extends and improves TextField, TextArea, DatePicker and maybe others (in the future).
Its a proper seperation of concerns, something that validation has needed for a while; a single "translator" converts back and forth between a server-side representation (int, Date, BigDecimal, etc.) and strings for the client side. A variable number of "validators" apply constraints to the converted value (such as minimum and maximum length for strings, or minimum and maximum values for numbers and dates). Of course, everything is just implementations of an interface, so its quite extensible.
In a flurry of work (I guess I ended up playing hooky from my paying client today), I integrated in the major portions of my client-side event bus. This has been necessitated by the need for different "flavors" of form onsubmit handlers: normal, refresh and cancel. normal triggers all validation, refresh limits the number of listeners (its primarily meant for refreshing the page when data, such as in a drop down list, changes), and cancel bypasses all other handlers.
I've also added a "translator:" binding prefix to make it easier to use Paul's changes, i.e.
<component id="inputDate" type="TextField"> <binding name="value" value="date"/> <binding name="translator" value="date"/> <binding name="validator" value="bean:dateValidator"/> </component>
However, I don't like having to configure a bean just to do the validation; I like that last parameter to be more like:
<binding name="validation" value="required,min=7/1/2005,max=12/31/2006"/>
And that means another smart binding factory for constructing and configuring a list of Validator objects.