Re: Multi field Validation improvement suggestion

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Multi field Validation improvement suggestion

Numa Schmeder
Sorry to respond so late.
On 5 mai 05, at 19:52, Paul Ferraro wrote:

> Numa Schmeder wrote:
>
>> Hello,
>>
>> Thanks to all for the feedback.
>> See my comment below:
>>
>> On 4 mai 05, at 21:00, Paul Ferraro wrote:
>>
>>> Numa Schmeder wrote:
>>>
>>>> Hello,
>>>>
>>>> I have read the tapestry blog about the new validators, and  i find  
>>>> the solution very neet.  But i would like to submit an idea that  
>>>> might be not realistic, but that i find nice.
>>>>
>>>> - 1 All fields should be validFields with by default no special  
>>>> validation.  The question is should a field with an empty input  
>>>> should update it's value as a null value or as an empty String?  
>>>> Actually a textField updates its binding as an empty String if  
>>>> there is no input, this seems to me strange, and maybe we should be  
>>>> able to have the option between empty or null.  For example if you  
>>>> use jdo or hibernate and you map your model objects to a tapestry  
>>>> form then all strings will be empty String (not null) and be  
>>>> inserted in the database as an empty varchar and not as a null  
>>>> value.  I hope you see my point.
>>>>
>>> Currently, the IValidator interface serves triple duty and is  
>>> responsible for:
>>> 1.  Indicating whether a field is required or not, and if so,  
>>> validating that a value was submitted.
>>> 2.  Translating the text submitted with the ValidField to an  
>>> appropriate typed value.
>>> 3.  Performing some validation on either the submitted text, or the  
>>> translated value.
>>> Consequently there is a lot of duplication of logic across  
>>> validators.
>>>
>>> In 4.0, I'm working on decoupling these responsibilities, breaking  
>>> up the IValidator into 3 pieces.
>>> 1. "required" - a new parameter for most form components, including  
>>> RadioGroup, Select, PropertySelection, Checkbox, TextField,  
>>> TextArea, DatePicker, and Upload.  If isRequired() is true (it will  
>>> default to false), and no value (or an empty value) is submitted,  
>>> then a validation error is recorded and rewinding of the component  
>>> is finished.
>>>
>>> Text driven fields, including TextField, TextArea, and DatePicker  
>>> will all have 2 additional parameters:
>>> 2. "translator" - a new Translator interface will be responsible for  
>>> translating the input text into its desired type.  Out-of-the-box  
>>> translators will include StringTranslator (includes a property to  
>>> determine whether an empty string will be interpreted as a null),  
>>> DateTranslator, and NumberTranslator (using  
>>> java.text.DecimalFormat).  TextArea's translator parameter will  
>>> default to a StringTranslator.  DatePicker's translator will default  
>>> to a DateTranslator.  Although TextField's translator will default  
>>> to StringTranslator, it value parameter will bind to an Object  
>>> (formerly value was bound to a String) so that it can use any  
>>> translator.  If the Translator fails to translate the submitted  
>>> text, then a validation error is recording and rewinding of the  
>>> component is finished.
>>>
>>     I think that implementing a translator is a great idea, because  
>> many time you need your values displayed differently as the way they  
>> are stored in the model.  But maybe the translator needs to be like a  
>> java.text.Format, the only bad things about the Format interface is  
>> that it is not very simple to implement and that is only one way.  
>> Thus using translator that can format data from the model to the view  
>> and then from the view to the model is a great idea, i would see it  
>> like cocoa translators if you know what i mean.
>>
> The Translator interface is used for both String to Object translation  
> (rewind) and Object to String translation (render).  Both the  
> NumberTranslator and DateTranslator will be java.text.Format-based  
> (using DecimalFormat and SimpleDateFormat, respectively).
>
>>> 3. "validators" - (a single Validator or list of Validators) a new  
>>> simplified Validator interface will be responsible for validating  
>>> the translated value (not the submitted text).  By making the  
>>> validators fine-grained, and by allowing multiple validators to be  
>>> used per field, we eliminate some more of the redundancy that exists  
>>> currently.  Out-of-the-box validators will include StringValidator  
>>> (maxLength, minLength), EmailValidator, RegExValidator,  
>>> EqualsValidator, and ComparableValidator (max, min).  If the  
>>> Validator fails to validate the translated value, then a validation  
>>> error is recording and rewinding of the component is finished.
>>>
>>> Consequently:
>>> a. The old IValidator interface can be deprecated.
>>> b. ValidField can be deprecated since it functionality is completely  
>>> achievable via the beefed up TextField.
>>>
>>> In Howard's blog, he suggests a new validator binding:
>>> <binding name="validator"  
>>> value="validator:string,required,minLength=3"/>
>>>
>>> Essentially, this is what I described above (i.e. the 3 validator  
>>> responsibilities) except that it's all smushed into a single  
>>> parameter.  I think the smushed representation is too cluttered.  
>>> Especially since the translator part (e.g. string) will use a most  
>>> often use a default value.  I sort of like the idea of defining a  
>>> validator inline (e.g. minLength=3), but I think it will get too  
>>> messy and complex, especially when I want to use custom (i.e.  
>>> non-framework) validator implementations.
>>
>>
>>    I agree that defining inline validator might not be the best, as  
>> when you want to define a custom validator it will be a completely  
>> different way to put it in the component.  I like the method of  
>> Howard because it is convenient for most simple case and that should  
>> be the default.  But as Howard said, in Tapestry 4 you can define new  
>> prefix, thus we can define a prefix for simple validation syntax  
>> 'value="validator:string,required,minLength=3"' and a prefix for  
>> backward compatible validator.  I think validation rules should not  
>> be tied to a field as in your suggestion, because a validation rule  
>> is tied to the logic of a form and not to the logic of a component,  
>> thus we would need to implement a new mechanism independent of per  
>> component validation but dependant of per form validation.  The other  
>> point is that most complex form validation are conditional, not all  
>> validation rule should be interpreted, validation rules should be  
>> interpreted only if a special condition is verified.  So maybe using  
>> your proposition of equal/comparable validator we should add a non  
>> mandatory property to the component that would be  
>> 'validatorCondition="myOtherComp.value == true"' if the condition is  
>> not verified then the validator should not display any error or  
>> should not be used.
>>
> Can you elaborate on what you mean be per form validation?  Why would  
> you not want to associate a validator with a field?  Can't cross-field  
> (i.e. per form) validation always be performed on the last field in  
> the validation set?
> Since "validators" will already be an optional parameter (currently,  
> this is not the case with ValidField), there's no real need for an  
> additional parameter to toggle it (although I admit it might make  
> things easier to read):
> e.g.
> <bean name="someValidator" class="..."/>
> <component id="someField" type="TextField">
>    <!-- ... -->
>    <binding name="validators" value="someCondition ?  
> beans.someValidator : null"/>
> </component>
>
   Ok, i see your point, and i must say you convince me.  This is a  
clean approach. Does someCondition is evaluated at rewind time ?  Most  
often condition will be based on form input.  The only point that might  
be complicated is involving javascript validation.  This way, it would  
be hard te create javascript validation (i might be mistaken).  Or an  
option is that validators would have a method that one could override  
to generate the javascript for this validator.  The method would take  
in argument the html field names generated by tapestry and would return  
a javascript snippet with a message.  This snippet could then be  
incorporated in a main javascript 'validate_myForm()' function.  Maybe  
even better, instead of a function we would define a ".script" file  
with its argument being a list of fields and their type (checkbox,  
textarea, input text etc..), and thus generate a javascript snippet  
that will be added to the main javascript validation function.  I don't  
if i am very clear on this one?!
The only problem with my proposal is then how do you integrate the  
someCondition in the javascript snippet generation as it is decoupled  
from the validator?


>>
>>
>>>
>>>> - 3 Multi component validation: I think it is possible to do a  
>>>> multi component validation using the Java Comparable interface, if  
>>>> the component implements the Comparable interface or delegate it to  
>>>> the validator  then we could compare components between them an  
>>>> write an expression this way i:
>>>> Suppose We have a check box, and two text fields component in the  
>>>> page
>>>> <validationRule>
>>>> <condition>myCheckbox == true </condition> //condition for this  
>>>> rule to be evaluated
>>>> <rule> passwd1 != passwd2 </rule> // rule to be evaluated
>>>> <message>For new customers the password 1 and the password 2 must  
>>>> be the same </message> // validation message to be displayed
>>>> </validationRule>
>>>> A special helper object would be used to interpret and verify the  
>>>> rule, the object would read this rule and interpret it as follow,  
>>>> get the value of myCheckbox component and verify if it si true then  
>>>> get the value of passwd1 field and compare it for equality to the  
>>>> value of passwd2.  We could use OGNL to do this. OGNL will  
>>>> interpret the ==, <, >, != using compare and equals, the components  
>>>> should override the equal and compare function to forward it to its  
>>>> value, thus calling passwd1 != passwd2 will be transformed in "if  
>>>> (!passwd1.equals(passwd1))" and the equals will be overwritten as  
>>>> follow:
>>>> public boolean equals(Object other) {
>>>>     if (!(other instanceof IFormComponent)) {
>>>>         throw Exception();
>>>>     }
>>>>     Object thisValue = this.getValue();
>>>>     Object otherValue = other.getValue();
>>>>     return    thisValue.equals(otherValue);
>>>> }
>>>>
>>>> The same would happen for the compareTo method, and if the value  
>>>> don't implement comparable then an exception should be thrown.  If  
>>>> the value are primitive then we make direct comparison of primitive  
>>>> value.
>>>>
>>> This is the intention of the EqualsValidator and ComparableValidator  
>>> mentioned above.  For instance, say I have a user registration page  
>>> where I ask the user to enter a password - typically a page will  
>>> show 2 text fields, the second being a "confirmation" that the user  
>>> didn't make a typing mistake when entering their password.  In this  
>>> scenario I would use an EqualsValidator to validate the equivalency  
>>> accross fields.  It might look roughly like the following (forgive  
>>> my inexperienced 4.0 syntax):
>>>
>>> <bean name="passwordValidator"  
>>> class="org.apache.tapestry.valid.StringValidator">
>>>    <set name="minLength" value="6"/>
>>>    <set name="maxLength" value="12"/>
>>> </bean>
>>> <bean name="patternValidator"  
>>> class="org.apache.tapestry.valid.PatternValidator">
>>>    <set name="pattern" value="... some regular expression ..."/>
>>> </bean>
>>> <bean name="confirmPasswordValidator"  
>>> class="org.apache.tapestry.valid.EqualsValidator">
>>>    <set name="value" value="ognl:user.password"/>
>>> </bean>
>>>
>>> <property name="user"/>
>>> <property name="confirmationPassword"/>
>>>
>>> <component id="password" type="TextField">
>>>    <binding name="value" value="ognl:user.password"/>
>>>    <binding name="label" value="Password"/>
>>>    <binding name="required" value="true"/>
>>>    <binding name="validators" value="{beans.passwordValidator,  
>>> beans.patternValidator}"/>
>>> </component>
>>> <component id="confirmPassword" type="TextField">
>>>    <binding name="value" value="ognl:confirmPassword"/>
>>>    <binding name="label" value="Confirmation Password"/>
>>>    <binding name="required" value="true"/>
>>>    <binding name="validators" value="bean:confirmPasswordValidator"/>
>>> </component>
>>>
>>> Thoughts?
>>>
>>    The problem i see with this method is that beans are instantiated  
>> for the lifecycle of the page, thus the confirmPasswordValidator  
>> value will not be updated during the rewind of the page, and the  
>> value will be the same through multiple request...  Maybe to avoid  
>> this problem, the confirmPasswordValidator should not hold the value  
>> of the component but the name or a reference to the component.
>>
> Sorry, I should have specified lifecycle="none" for the  
> confirmPasswordValidator.  That works, no?
> The other point to make is that validation (after it is decoupled from  
> translation) acts on your model, not fields.  That is why I compare  
> "user.password" instead "components.confirmPassword.value".  The  
> difference becomes clearer if the values were bound to numbers or  
> dates.
>
> Paul
>
>> Numa
>>
>>> Paul
>>>
>>>> The following scenario is quite simple, but we could name  
>>>> validationRules and thus validationRules could be dependant of the  
>>>> success of other validationRules.
>>>> I don't really know if this is realistic, but it seems to me  
>>>> possible, the problem is i don't know yet enough about the  
>>>> internals of tapestry and the page specification parser.
>>>> But to implement this solution i would see that we need to change  
>>>> the following things:
>>>>     -  modify the page / component specification parser to add  
>>>> support for reading the validationRule (Page/component DTD)
>>>>     -  add a helper bean that records the validation rule and their  
>>>> imbrication and interpret then during page rewinding
>>>>     - All validField component or formComponent  should implement  
>>>> comparable and overwrite equals
>>>>
>>>> In my absolut dreams we could even imagine that the helper bean  
>>>> translate this rule in javascript. or that in the specification we  
>>>> provide a script snippet that performs the validation.
>>>>
>>>> Maybe i am dreaming eyes open ;)
>>>>
>>>> Please give me some feedback about this idea if you think it is  
>>>> positive or not so maybe i try to dig more inside tapestry.
>>>>
>>>> Kind Regards
>>>>
>>>> Numa
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> --------------------------------------------------------------------
>>>> -
>>>> To unsubscribe, e-mail: [hidden email]
>>>> For additional commands, e-mail:  
>>>> [hidden email]
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [hidden email]
>>> For additional commands, e-mail: [hidden email]
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multi field Validation improvement suggestion

Howard Lewis Ship
I've been thinking a lot about how JavaScript on the client side, and
Tapestry, interact.

I think the current Tapestry approach is somewhat limiting.

I would like to put together a simple client-side event bus, tailored
to Tapestry's useage.

This would be useful for Forms, and would give us more flexibility on
the client side.

There would be some Tapestry-specific events on the bus, such as
"validate this form".

Right now, it would be very, very hard to, say, run all the
validations and update the HTML to display an error message beside
each field (or, alternately, to display error messages at the top of
the form).  And clear those error messages as the fields are correct
(or on the next attempted submit).  Accomplishing that with an event
bus would be easier (but there's still some unknowns).

On 5/7/05, Numa Schmeder <[hidden email]> wrote:

> Sorry to respond so late.
> On 5 mai 05, at 19:52, Paul Ferraro wrote:
>
> > Numa Schmeder wrote:
> >
> >> Hello,
> >>
> >> Thanks to all for the feedback.
> >> See my comment below:
> >>
> >> On 4 mai 05, at 21:00, Paul Ferraro wrote:
> >>
> >>> Numa Schmeder wrote:
> >>>
> >>>> Hello,
> >>>>
> >>>> I have read the tapestry blog about the new validators, and  i find
> >>>> the solution very neet.  But i would like to submit an idea that
> >>>> might be not realistic, but that i find nice.
> >>>>
> >>>> - 1 All fields should be validFields with by default no special
> >>>> validation.  The question is should a field with an empty input
> >>>> should update it's value as a null value or as an empty String?
> >>>> Actually a textField updates its binding as an empty String if
> >>>> there is no input, this seems to me strange, and maybe we should be
> >>>> able to have the option between empty or null.  For example if you
> >>>> use jdo or hibernate and you map your model objects to a tapestry
> >>>> form then all strings will be empty String (not null) and be
> >>>> inserted in the database as an empty varchar and not as a null
> >>>> value.  I hope you see my point.
> >>>>
> >>> Currently, the IValidator interface serves triple duty and is
> >>> responsible for:
> >>> 1.  Indicating whether a field is required or not, and if so,
> >>> validating that a value was submitted.
> >>> 2.  Translating the text submitted with the ValidField to an
> >>> appropriate typed value.
> >>> 3.  Performing some validation on either the submitted text, or the
> >>> translated value.
> >>> Consequently there is a lot of duplication of logic across
> >>> validators.
> >>>
> >>> In 4.0, I'm working on decoupling these responsibilities, breaking
> >>> up the IValidator into 3 pieces.
> >>> 1. "required" - a new parameter for most form components, including
> >>> RadioGroup, Select, PropertySelection, Checkbox, TextField,
> >>> TextArea, DatePicker, and Upload.  If isRequired() is true (it will
> >>> default to false), and no value (or an empty value) is submitted,
> >>> then a validation error is recorded and rewinding of the component
> >>> is finished.
> >>>
> >>> Text driven fields, including TextField, TextArea, and DatePicker
> >>> will all have 2 additional parameters:
> >>> 2. "translator" - a new Translator interface will be responsible for
> >>> translating the input text into its desired type.  Out-of-the-box
> >>> translators will include StringTranslator (includes a property to
> >>> determine whether an empty string will be interpreted as a null),
> >>> DateTranslator, and NumberTranslator (using
> >>> java.text.DecimalFormat).  TextArea's translator parameter will
> >>> default to a StringTranslator.  DatePicker's translator will default
> >>> to a DateTranslator.  Although TextField's translator will default
> >>> to StringTranslator, it value parameter will bind to an Object
> >>> (formerly value was bound to a String) so that it can use any
> >>> translator.  If the Translator fails to translate the submitted
> >>> text, then a validation error is recording and rewinding of the
> >>> component is finished.
> >>>
> >>     I think that implementing a translator is a great idea, because
> >> many time you need your values displayed differently as the way they
> >> are stored in the model.  But maybe the translator needs to be like a
> >> java.text.Format, the only bad things about the Format interface is
> >> that it is not very simple to implement and that is only one way.
> >> Thus using translator that can format data from the model to the view
> >> and then from the view to the model is a great idea, i would see it
> >> like cocoa translators if you know what i mean.
> >>
> > The Translator interface is used for both String to Object translation
> > (rewind) and Object to String translation (render).  Both the
> > NumberTranslator and DateTranslator will be java.text.Format-based
> > (using DecimalFormat and SimpleDateFormat, respectively).
> >
> >>> 3. "validators" - (a single Validator or list of Validators) a new
> >>> simplified Validator interface will be responsible for validating
> >>> the translated value (not the submitted text).  By making the
> >>> validators fine-grained, and by allowing multiple validators to be
> >>> used per field, we eliminate some more of the redundancy that exists
> >>> currently.  Out-of-the-box validators will include StringValidator
> >>> (maxLength, minLength), EmailValidator, RegExValidator,
> >>> EqualsValidator, and ComparableValidator (max, min).  If the
> >>> Validator fails to validate the translated value, then a validation
> >>> error is recording and rewinding of the component is finished.
> >>>
> >>> Consequently:
> >>> a. The old IValidator interface can be deprecated.
> >>> b. ValidField can be deprecated since it functionality is completely
> >>> achievable via the beefed up TextField.
> >>>
> >>> In Howard's blog, he suggests a new validator binding:
> >>> <binding name="validator"
> >>> value="validator:string,required,minLength=3"/>
> >>>
> >>> Essentially, this is what I described above (i.e. the 3 validator
> >>> responsibilities) except that it's all smushed into a single
> >>> parameter.  I think the smushed representation is too cluttered.
> >>> Especially since the translator part (e.g. string) will use a most
> >>> often use a default value.  I sort of like the idea of defining a
> >>> validator inline (e.g. minLength=3), but I think it will get too
> >>> messy and complex, especially when I want to use custom (i.e.
> >>> non-framework) validator implementations.
> >>
> >>
> >>    I agree that defining inline validator might not be the best, as
> >> when you want to define a custom validator it will be a completely
> >> different way to put it in the component.  I like the method of
> >> Howard because it is convenient for most simple case and that should
> >> be the default.  But as Howard said, in Tapestry 4 you can define new
> >> prefix, thus we can define a prefix for simple validation syntax
> >> 'value="validator:string,required,minLength=3"' and a prefix for
> >> backward compatible validator.  I think validation rules should not
> >> be tied to a field as in your suggestion, because a validation rule
> >> is tied to the logic of a form and not to the logic of a component,
> >> thus we would need to implement a new mechanism independent of per
> >> component validation but dependant of per form validation.  The other
> >> point is that most complex form validation are conditional, not all
> >> validation rule should be interpreted, validation rules should be
> >> interpreted only if a special condition is verified.  So maybe using
> >> your proposition of equal/comparable validator we should add a non
> >> mandatory property to the component that would be
> >> 'validatorCondition="myOtherComp.value == true"' if the condition is
> >> not verified then the validator should not display any error or
> >> should not be used.
> >>
> > Can you elaborate on what you mean be per form validation?  Why would
> > you not want to associate a validator with a field?  Can't cross-field
> > (i.e. per form) validation always be performed on the last field in
> > the validation set?
> > Since "validators" will already be an optional parameter (currently,
> > this is not the case with ValidField), there's no real need for an
> > additional parameter to toggle it (although I admit it might make
> > things easier to read):
> > e.g.
> > <bean name="someValidator" class="..."/>
> > <component id="someField" type="TextField">
> >    <!-- ... -->
> >    <binding name="validators" value="someCondition ?
> > beans.someValidator : null"/>
> > </component>
> >
>    Ok, i see your point, and i must say you convince me.  This is a
> clean approach. Does someCondition is evaluated at rewind time ?  Most
> often condition will be based on form input.  The only point that might
> be complicated is involving javascript validation.  This way, it would
> be hard te create javascript validation (i might be mistaken).  Or an
> option is that validators would have a method that one could override
> to generate the javascript for this validator.  The method would take
> in argument the html field names generated by tapestry and would return
> a javascript snippet with a message.  This snippet could then be
> incorporated in a main javascript 'validate_myForm()' function.  Maybe
> even better, instead of a function we would define a ".script" file
> with its argument being a list of fields and their type (checkbox,
> textarea, input text etc..), and thus generate a javascript snippet
> that will be added to the main javascript validation function.  I don't
> if i am very clear on this one?!
> The only problem with my proposal is then how do you integrate the
> someCondition in the javascript snippet generation as it is decoupled
> from the validator?
>
>
> >>
> >>
> >>>
> >>>> - 3 Multi component validation: I think it is possible to do a
> >>>> multi component validation using the Java Comparable interface, if
> >>>> the component implements the Comparable interface or delegate it to
> >>>> the validator  then we could compare components between them an
> >>>> write an expression this way i:
> >>>> Suppose We have a check box, and two text fields component in the
> >>>> page
> >>>> <validationRule>
> >>>> <condition>myCheckbox == true </condition> //condition for this
> >>>> rule to be evaluated
> >>>> <rule> passwd1 != passwd2 </rule> // rule to be evaluated
> >>>> <message>For new customers the password 1 and the password 2 must
> >>>> be the same </message> // validation message to be displayed
> >>>> </validationRule>
> >>>> A special helper object would be used to interpret and verify the
> >>>> rule, the object would read this rule and interpret it as follow,
> >>>> get the value of myCheckbox component and verify if it si true then
> >>>> get the value of passwd1 field and compare it for equality to the
> >>>> value of passwd2.  We could use OGNL to do this. OGNL will
> >>>> interpret the ==, <, >, != using compare and equals, the components
> >>>> should override the equal and compare function to forward it to its
> >>>> value, thus calling passwd1 != passwd2 will be transformed in "if
> >>>> (!passwd1.equals(passwd1))" and the equals will be overwritten as
> >>>> follow:
> >>>> public boolean equals(Object other) {
> >>>>     if (!(other instanceof IFormComponent)) {
> >>>>         throw Exception();
> >>>>     }
> >>>>     Object thisValue = this.getValue();
> >>>>     Object otherValue = other.getValue();
> >>>>     return    thisValue.equals(otherValue);
> >>>> }
> >>>>
> >>>> The same would happen for the compareTo method, and if the value
> >>>> don't implement comparable then an exception should be thrown.  If
> >>>> the value are primitive then we make direct comparison of primitive
> >>>> value.
> >>>>
> >>> This is the intention of the EqualsValidator and ComparableValidator
> >>> mentioned above.  For instance, say I have a user registration page
> >>> where I ask the user to enter a password - typically a page will
> >>> show 2 text fields, the second being a "confirmation" that the user
> >>> didn't make a typing mistake when entering their password.  In this
> >>> scenario I would use an EqualsValidator to validate the equivalency
> >>> accross fields.  It might look roughly like the following (forgive
> >>> my inexperienced 4.0 syntax):
> >>>
> >>> <bean name="passwordValidator"
> >>> class="org.apache.tapestry.valid.StringValidator">
> >>>    <set name="minLength" value="6"/>
> >>>    <set name="maxLength" value="12"/>
> >>> </bean>
> >>> <bean name="patternValidator"
> >>> class="org.apache.tapestry.valid.PatternValidator">
> >>>    <set name="pattern" value="... some regular expression ..."/>
> >>> </bean>
> >>> <bean name="confirmPasswordValidator"
> >>> class="org.apache.tapestry.valid.EqualsValidator">
> >>>    <set name="value" value="ognl:user.password"/>
> >>> </bean>
> >>>
> >>> <property name="user"/>
> >>> <property name="confirmationPassword"/>
> >>>
> >>> <component id="password" type="TextField">
> >>>    <binding name="value" value="ognl:user.password"/>
> >>>    <binding name="label" value="Password"/>
> >>>    <binding name="required" value="true"/>
> >>>    <binding name="validators" value="{beans.passwordValidator,
> >>> beans.patternValidator}"/>
> >>> </component>
> >>> <component id="confirmPassword" type="TextField">
> >>>    <binding name="value" value="ognl:confirmPassword"/>
> >>>    <binding name="label" value="Confirmation Password"/>
> >>>    <binding name="required" value="true"/>
> >>>    <binding name="validators" value="bean:confirmPasswordValidator"/>
> >>> </component>
> >>>
> >>> Thoughts?
> >>>
> >>    The problem i see with this method is that beans are instantiated
> >> for the lifecycle of the page, thus the confirmPasswordValidator
> >> value will not be updated during the rewind of the page, and the
> >> value will be the same through multiple request...  Maybe to avoid
> >> this problem, the confirmPasswordValidator should not hold the value
> >> of the component but the name or a reference to the component.
> >>
> > Sorry, I should have specified lifecycle="none" for the
> > confirmPasswordValidator.  That works, no?
> > The other point to make is that validation (after it is decoupled from
> > translation) acts on your model, not fields.  That is why I compare
> > "user.password" instead "components.confirmPassword.value".  The
> > difference becomes clearer if the values were bound to numbers or
> > dates.
> >
> > Paul
> >
> >> Numa
> >>
> >>> Paul
> >>>
> >>>> The following scenario is quite simple, but we could name
> >>>> validationRules and thus validationRules could be dependant of the
> >>>> success of other validationRules.
> >>>> I don't really know if this is realistic, but it seems to me
> >>>> possible, the problem is i don't know yet enough about the
> >>>> internals of tapestry and the page specification parser.
> >>>> But to implement this solution i would see that we need to change
> >>>> the following things:
> >>>>     -  modify the page / component specification parser to add
> >>>> support for reading the validationRule (Page/component DTD)
> >>>>     -  add a helper bean that records the validation rule and their
> >>>> imbrication and interpret then during page rewinding
> >>>>     - All validField component or formComponent  should implement
> >>>> comparable and overwrite equals
> >>>>
> >>>> In my absolut dreams we could even imagine that the helper bean
> >>>> translate this rule in javascript. or that in the specification we
> >>>> provide a script snippet that performs the validation.
> >>>>
> >>>> Maybe i am dreaming eyes open ;)
> >>>>
> >>>> Please give me some feedback about this idea if you think it is
> >>>> positive or not so maybe i try to dig more inside tapestry.
> >>>>
> >>>> Kind Regards
> >>>>
> >>>> Numa
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> --------------------------------------------------------------------
> >>>> -
> >>>> To unsubscribe, e-mail: [hidden email]
> >>>> For additional commands, e-mail:
> >>>> [hidden email]
> >>>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [hidden email]
> >>> For additional commands, e-mail: [hidden email]
> >>>
> >>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [hidden email]
> >> For additional commands, e-mail: [hidden email]
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multi field Validation improvement suggestion

Howard Lewis Ship
Hm.  Imagine something like:

var formValidationErrors;
var tapestry_eventbus = ....;

function myform_onsubmit()
{
  formValidationErrors = false;

  tapestry_eventbus.fireValidateForm("myform");

  return formValidationErrors;
}


Each field register a "validate form" event listener, and sets
formValidationErrors:

function myfield_validate()
{
  if (document.myform.myfield != "") return;


  tapestry_eventbus.fireFormValidationError("myform", "myfield", "A
value for My Field is required.");
}

The ValidationDelegate would register the listener for this event, and
would be responsible for client-side UI.  Default delegate raises a
window (for the first error); a sophisticated delegate could do more
aggresive DHTML.

On 5/7/05, Howard Lewis Ship <[hidden email]> wrote:

> I've been thinking a lot about how JavaScript on the client side, and
> Tapestry, interact.
>
> I think the current Tapestry approach is somewhat limiting.
>
> I would like to put together a simple client-side event bus, tailored
> to Tapestry's useage.
>
> This would be useful for Forms, and would give us more flexibility on
> the client side.
>
> There would be some Tapestry-specific events on the bus, such as
> "validate this form".
>
> Right now, it would be very, very hard to, say, run all the
> validations and update the HTML to display an error message beside
> each field (or, alternately, to display error messages at the top of
> the form).  And clear those error messages as the fields are correct
> (or on the next attempted submit).  Accomplishing that with an event
> bus would be easier (but there's still some unknowns).
>
> On 5/7/05, Numa Schmeder <[hidden email]> wrote:
> > Sorry to respond so late.
> > On 5 mai 05, at 19:52, Paul Ferraro wrote:
> >
> > > Numa Schmeder wrote:
> > >
> > >> Hello,
> > >>
> > >> Thanks to all for the feedback.
> > >> See my comment below:
> > >>
> > >> On 4 mai 05, at 21:00, Paul Ferraro wrote:
> > >>
> > >>> Numa Schmeder wrote:
> > >>>
> > >>>> Hello,
> > >>>>
> > >>>> I have read the tapestry blog about the new validators, and  i find
> > >>>> the solution very neet.  But i would like to submit an idea that
> > >>>> might be not realistic, but that i find nice.
> > >>>>
> > >>>> - 1 All fields should be validFields with by default no special
> > >>>> validation.  The question is should a field with an empty input
> > >>>> should update it's value as a null value or as an empty String?
> > >>>> Actually a textField updates its binding as an empty String if
> > >>>> there is no input, this seems to me strange, and maybe we should be
> > >>>> able to have the option between empty or null.  For example if you
> > >>>> use jdo or hibernate and you map your model objects to a tapestry
> > >>>> form then all strings will be empty String (not null) and be
> > >>>> inserted in the database as an empty varchar and not as a null
> > >>>> value.  I hope you see my point.
> > >>>>
> > >>> Currently, the IValidator interface serves triple duty and is
> > >>> responsible for:
> > >>> 1.  Indicating whether a field is required or not, and if so,
> > >>> validating that a value was submitted.
> > >>> 2.  Translating the text submitted with the ValidField to an
> > >>> appropriate typed value.
> > >>> 3.  Performing some validation on either the submitted text, or the
> > >>> translated value.
> > >>> Consequently there is a lot of duplication of logic across
> > >>> validators.
> > >>>
> > >>> In 4.0, I'm working on decoupling these responsibilities, breaking
> > >>> up the IValidator into 3 pieces.
> > >>> 1. "required" - a new parameter for most form components, including
> > >>> RadioGroup, Select, PropertySelection, Checkbox, TextField,
> > >>> TextArea, DatePicker, and Upload.  If isRequired() is true (it will
> > >>> default to false), and no value (or an empty value) is submitted,
> > >>> then a validation error is recorded and rewinding of the component
> > >>> is finished.
> > >>>
> > >>> Text driven fields, including TextField, TextArea, and DatePicker
> > >>> will all have 2 additional parameters:
> > >>> 2. "translator" - a new Translator interface will be responsible for
> > >>> translating the input text into its desired type.  Out-of-the-box
> > >>> translators will include StringTranslator (includes a property to
> > >>> determine whether an empty string will be interpreted as a null),
> > >>> DateTranslator, and NumberTranslator (using
> > >>> java.text.DecimalFormat).  TextArea's translator parameter will
> > >>> default to a StringTranslator.  DatePicker's translator will default
> > >>> to a DateTranslator.  Although TextField's translator will default
> > >>> to StringTranslator, it value parameter will bind to an Object
> > >>> (formerly value was bound to a String) so that it can use any
> > >>> translator.  If the Translator fails to translate the submitted
> > >>> text, then a validation error is recording and rewinding of the
> > >>> component is finished.
> > >>>
> > >>     I think that implementing a translator is a great idea, because
> > >> many time you need your values displayed differently as the way they
> > >> are stored in the model.  But maybe the translator needs to be like a
> > >> java.text.Format, the only bad things about the Format interface is
> > >> that it is not very simple to implement and that is only one way.
> > >> Thus using translator that can format data from the model to the view
> > >> and then from the view to the model is a great idea, i would see it
> > >> like cocoa translators if you know what i mean.
> > >>
> > > The Translator interface is used for both String to Object translation
> > > (rewind) and Object to String translation (render).  Both the
> > > NumberTranslator and DateTranslator will be java.text.Format-based
> > > (using DecimalFormat and SimpleDateFormat, respectively).
> > >
> > >>> 3. "validators" - (a single Validator or list of Validators) a new
> > >>> simplified Validator interface will be responsible for validating
> > >>> the translated value (not the submitted text).  By making the
> > >>> validators fine-grained, and by allowing multiple validators to be
> > >>> used per field, we eliminate some more of the redundancy that exists
> > >>> currently.  Out-of-the-box validators will include StringValidator
> > >>> (maxLength, minLength), EmailValidator, RegExValidator,
> > >>> EqualsValidator, and ComparableValidator (max, min).  If the
> > >>> Validator fails to validate the translated value, then a validation
> > >>> error is recording and rewinding of the component is finished.
> > >>>
> > >>> Consequently:
> > >>> a. The old IValidator interface can be deprecated.
> > >>> b. ValidField can be deprecated since it functionality is completely
> > >>> achievable via the beefed up TextField.
> > >>>
> > >>> In Howard's blog, he suggests a new validator binding:
> > >>> <binding name="validator"
> > >>> value="validator:string,required,minLength=3"/>
> > >>>
> > >>> Essentially, this is what I described above (i.e. the 3 validator
> > >>> responsibilities) except that it's all smushed into a single
> > >>> parameter.  I think the smushed representation is too cluttered.
> > >>> Especially since the translator part (e.g. string) will use a most
> > >>> often use a default value.  I sort of like the idea of defining a
> > >>> validator inline (e.g. minLength=3), but I think it will get too
> > >>> messy and complex, especially when I want to use custom (i.e.
> > >>> non-framework) validator implementations.
> > >>
> > >>
> > >>    I agree that defining inline validator might not be the best, as
> > >> when you want to define a custom validator it will be a completely
> > >> different way to put it in the component.  I like the method of
> > >> Howard because it is convenient for most simple case and that should
> > >> be the default.  But as Howard said, in Tapestry 4 you can define new
> > >> prefix, thus we can define a prefix for simple validation syntax
> > >> 'value="validator:string,required,minLength=3"' and a prefix for
> > >> backward compatible validator.  I think validation rules should not
> > >> be tied to a field as in your suggestion, because a validation rule
> > >> is tied to the logic of a form and not to the logic of a component,
> > >> thus we would need to implement a new mechanism independent of per
> > >> component validation but dependant of per form validation.  The other
> > >> point is that most complex form validation are conditional, not all
> > >> validation rule should be interpreted, validation rules should be
> > >> interpreted only if a special condition is verified.  So maybe using
> > >> your proposition of equal/comparable validator we should add a non
> > >> mandatory property to the component that would be
> > >> 'validatorCondition="myOtherComp.value == true"' if the condition is
> > >> not verified then the validator should not display any error or
> > >> should not be used.
> > >>
> > > Can you elaborate on what you mean be per form validation?  Why would
> > > you not want to associate a validator with a field?  Can't cross-field
> > > (i.e. per form) validation always be performed on the last field in
> > > the validation set?
> > > Since "validators" will already be an optional parameter (currently,
> > > this is not the case with ValidField), there's no real need for an
> > > additional parameter to toggle it (although I admit it might make
> > > things easier to read):
> > > e.g.
> > > <bean name="someValidator" class="..."/>
> > > <component id="someField" type="TextField">
> > >    <!-- ... -->
> > >    <binding name="validators" value="someCondition ?
> > > beans.someValidator : null"/>
> > > </component>
> > >
> >    Ok, i see your point, and i must say you convince me.  This is a
> > clean approach. Does someCondition is evaluated at rewind time ?  Most
> > often condition will be based on form input.  The only point that might
> > be complicated is involving javascript validation.  This way, it would
> > be hard te create javascript validation (i might be mistaken).  Or an
> > option is that validators would have a method that one could override
> > to generate the javascript for this validator.  The method would take
> > in argument the html field names generated by tapestry and would return
> > a javascript snippet with a message.  This snippet could then be
> > incorporated in a main javascript 'validate_myForm()' function.  Maybe
> > even better, instead of a function we would define a ".script" file
> > with its argument being a list of fields and their type (checkbox,
> > textarea, input text etc..), and thus generate a javascript snippet
> > that will be added to the main javascript validation function.  I don't
> > if i am very clear on this one?!
> > The only problem with my proposal is then how do you integrate the
> > someCondition in the javascript snippet generation as it is decoupled
> > from the validator?
> >
> >
> > >>
> > >>
> > >>>
> > >>>> - 3 Multi component validation: I think it is possible to do a
> > >>>> multi component validation using the Java Comparable interface, if
> > >>>> the component implements the Comparable interface or delegate it to
> > >>>> the validator  then we could compare components between them an
> > >>>> write an expression this way i:
> > >>>> Suppose We have a check box, and two text fields component in the
> > >>>> page
> > >>>> <validationRule>
> > >>>> <condition>myCheckbox == true </condition> //condition for this
> > >>>> rule to be evaluated
> > >>>> <rule> passwd1 != passwd2 </rule> // rule to be evaluated
> > >>>> <message>For new customers the password 1 and the password 2 must
> > >>>> be the same </message> // validation message to be displayed
> > >>>> </validationRule>
> > >>>> A special helper object would be used to interpret and verify the
> > >>>> rule, the object would read this rule and interpret it as follow,
> > >>>> get the value of myCheckbox component and verify if it si true then
> > >>>> get the value of passwd1 field and compare it for equality to the
> > >>>> value of passwd2.  We could use OGNL to do this. OGNL will
> > >>>> interpret the ==, <, >, != using compare and equals, the components
> > >>>> should override the equal and compare function to forward it to its
> > >>>> value, thus calling passwd1 != passwd2 will be transformed in "if
> > >>>> (!passwd1.equals(passwd1))" and the equals will be overwritten as
> > >>>> follow:
> > >>>> public boolean equals(Object other) {
> > >>>>     if (!(other instanceof IFormComponent)) {
> > >>>>         throw Exception();
> > >>>>     }
> > >>>>     Object thisValue = this.getValue();
> > >>>>     Object otherValue = other.getValue();
> > >>>>     return    thisValue.equals(otherValue);
> > >>>> }
> > >>>>
> > >>>> The same would happen for the compareTo method, and if the value
> > >>>> don't implement comparable then an exception should be thrown.  If
> > >>>> the value are primitive then we make direct comparison of primitive
> > >>>> value.
> > >>>>
> > >>> This is the intention of the EqualsValidator and ComparableValidator
> > >>> mentioned above.  For instance, say I have a user registration page
> > >>> where I ask the user to enter a password - typically a page will
> > >>> show 2 text fields, the second being a "confirmation" that the user
> > >>> didn't make a typing mistake when entering their password.  In this
> > >>> scenario I would use an EqualsValidator to validate the equivalency
> > >>> accross fields.  It might look roughly like the following (forgive
> > >>> my inexperienced 4.0 syntax):
> > >>>
> > >>> <bean name="passwordValidator"
> > >>> class="org.apache.tapestry.valid.StringValidator">
> > >>>    <set name="minLength" value="6"/>
> > >>>    <set name="maxLength" value="12"/>
> > >>> </bean>
> > >>> <bean name="patternValidator"
> > >>> class="org.apache.tapestry.valid.PatternValidator">
> > >>>    <set name="pattern" value="... some regular expression ..."/>
> > >>> </bean>
> > >>> <bean name="confirmPasswordValidator"
> > >>> class="org.apache.tapestry.valid.EqualsValidator">
> > >>>    <set name="value" value="ognl:user.password"/>
> > >>> </bean>
> > >>>
> > >>> <property name="user"/>
> > >>> <property name="confirmationPassword"/>
> > >>>
> > >>> <component id="password" type="TextField">
> > >>>    <binding name="value" value="ognl:user.password"/>
> > >>>    <binding name="label" value="Password"/>
> > >>>    <binding name="required" value="true"/>
> > >>>    <binding name="validators" value="{beans.passwordValidator,
> > >>> beans.patternValidator}"/>
> > >>> </component>
> > >>> <component id="confirmPassword" type="TextField">
> > >>>    <binding name="value" value="ognl:confirmPassword"/>
> > >>>    <binding name="label" value="Confirmation Password"/>
> > >>>    <binding name="required" value="true"/>
> > >>>    <binding name="validators" value="bean:confirmPasswordValidator"/>
> > >>> </component>
> > >>>
> > >>> Thoughts?
> > >>>
> > >>    The problem i see with this method is that beans are instantiated
> > >> for the lifecycle of the page, thus the confirmPasswordValidator
> > >> value will not be updated during the rewind of the page, and the
> > >> value will be the same through multiple request...  Maybe to avoid
> > >> this problem, the confirmPasswordValidator should not hold the value
> > >> of the component but the name or a reference to the component.
> > >>
> > > Sorry, I should have specified lifecycle="none" for the
> > > confirmPasswordValidator.  That works, no?
> > > The other point to make is that validation (after it is decoupled from
> > > translation) acts on your model, not fields.  That is why I compare
> > > "user.password" instead "components.confirmPassword.value".  The
> > > difference becomes clearer if the values were bound to numbers or
> > > dates.
> > >
> > > Paul
> > >
> > >> Numa
> > >>
> > >>> Paul
> > >>>
> > >>>> The following scenario is quite simple, but we could name
> > >>>> validationRules and thus validationRules could be dependant of the
> > >>>> success of other validationRules.
> > >>>> I don't really know if this is realistic, but it seems to me
> > >>>> possible, the problem is i don't know yet enough about the
> > >>>> internals of tapestry and the page specification parser.
> > >>>> But to implement this solution i would see that we need to change
> > >>>> the following things:
> > >>>>     -  modify the page / component specification parser to add
> > >>>> support for reading the validationRule (Page/component DTD)
> > >>>>     -  add a helper bean that records the validation rule and their
> > >>>> imbrication and interpret then during page rewinding
> > >>>>     - All validField component or formComponent  should implement
> > >>>> comparable and overwrite equals
> > >>>>
> > >>>> In my absolut dreams we could even imagine that the helper bean
> > >>>> translate this rule in javascript. or that in the specification we
> > >>>> provide a script snippet that performs the validation.
> > >>>>
> > >>>> Maybe i am dreaming eyes open ;)
> > >>>>
> > >>>> Please give me some feedback about this idea if you think it is
> > >>>> positive or not so maybe i try to dig more inside tapestry.
> > >>>>
> > >>>> Kind Regards
> > >>>>
> > >>>> Numa
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>> --------------------------------------------------------------------
> > >>>> -
> > >>>> To unsubscribe, e-mail: [hidden email]
> > >>>> For additional commands, e-mail:
> > >>>> [hidden email]
> > >>>>
> > >>>
> > >>>
> > >>> ---------------------------------------------------------------------
> > >>> To unsubscribe, e-mail: [hidden email]
> > >>> For additional commands, e-mail: [hidden email]
> > >>>
> > >>>
> > >>
> > >>
> > >> ---------------------------------------------------------------------
> > >> To unsubscribe, e-mail: [hidden email]
> > >> For additional commands, e-mail: [hidden email]
> > >>
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [hidden email]
> > > For additional commands, e-mail: [hidden email]
> > >
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >
>
> --
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
>
> Professional Tapestry training, mentoring, support
> and project work.  http://howardlewisship.com
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multi field Validation improvement suggestion

Karthik Abram
In reply to this post by Howard Lewis Ship

It is not as difficult as you think. I've got a custom validation
implementation that allows you to have multiple error messages tied to input
fields and these can appear in a Foreach loop and still render correctly.
You simply tell the fields which component they validate against. They can
appear before or after the input element. They currently support two
behaviors - changing the css of an element, or causing an element to appear
and disappear. The associated javascript will flag and display each error
message and on a subsequent submit clear the ones that pass.

I use a validation manager that all error display and input fields register
with. The validation manager provides each compoonent with a proper
reference to the other and this way hooks everyone up. Finally the
components emit their javascript and everything gets stitched together. Ok,
I am simplifying things a bit here. The validation manager also supports
disabling all validation (javascript and serverside) on form-submit and this
can be controlled by javascript!



-----Original Message-----
From: Howard Lewis Ship [mailto:[hidden email]]
Sent: Saturday, May 07, 2005 8:48 AM
To: Tapestry development
Subject: Re: Multi field Validation improvement suggestion


I've been thinking a lot about how JavaScript on the client side, and
Tapestry, interact.

I think the current Tapestry approach is somewhat limiting.

I would like to put together a simple client-side event bus, tailored
to Tapestry's useage.

This would be useful for Forms, and would give us more flexibility on
the client side.

There would be some Tapestry-specific events on the bus, such as
"validate this form".

Right now, it would be very, very hard to, say, run all the
validations and update the HTML to display an error message beside
each field (or, alternately, to display error messages at the top of
the form).  And clear those error messages as the fields are correct
(or on the next attempted submit).  Accomplishing that with an event
bus would be easier (but there's still some unknowns).

On 5/7/05, Numa Schmeder <[hidden email]> wrote:

> Sorry to respond so late.
> On 5 mai 05, at 19:52, Paul Ferraro wrote:
>
> > Numa Schmeder wrote:
> >
> >> Hello,
> >>
> >> Thanks to all for the feedback.
> >> See my comment below:
> >>
> >> On 4 mai 05, at 21:00, Paul Ferraro wrote:
> >>
> >>> Numa Schmeder wrote:
> >>>
> >>>> Hello,
> >>>>
> >>>> I have read the tapestry blog about the new validators, and  i find
> >>>> the solution very neet.  But i would like to submit an idea that
> >>>> might be not realistic, but that i find nice.
> >>>>
> >>>> - 1 All fields should be validFields with by default no special
> >>>> validation.  The question is should a field with an empty input
> >>>> should update it's value as a null value or as an empty String?
> >>>> Actually a textField updates its binding as an empty String if
> >>>> there is no input, this seems to me strange, and maybe we should be
> >>>> able to have the option between empty or null.  For example if you
> >>>> use jdo or hibernate and you map your model objects to a tapestry
> >>>> form then all strings will be empty String (not null) and be
> >>>> inserted in the database as an empty varchar and not as a null
> >>>> value.  I hope you see my point.
> >>>>
> >>> Currently, the IValidator interface serves triple duty and is
> >>> responsible for:
> >>> 1.  Indicating whether a field is required or not, and if so,
> >>> validating that a value was submitted.
> >>> 2.  Translating the text submitted with the ValidField to an
> >>> appropriate typed value.
> >>> 3.  Performing some validation on either the submitted text, or the
> >>> translated value.
> >>> Consequently there is a lot of duplication of logic across
> >>> validators.
> >>>
> >>> In 4.0, I'm working on decoupling these responsibilities, breaking
> >>> up the IValidator into 3 pieces.
> >>> 1. "required" - a new parameter for most form components, including
> >>> RadioGroup, Select, PropertySelection, Checkbox, TextField,
> >>> TextArea, DatePicker, and Upload.  If isRequired() is true (it will
> >>> default to false), and no value (or an empty value) is submitted,
> >>> then a validation error is recorded and rewinding of the component
> >>> is finished.
> >>>
> >>> Text driven fields, including TextField, TextArea, and DatePicker
> >>> will all have 2 additional parameters:
> >>> 2. "translator" - a new Translator interface will be responsible for
> >>> translating the input text into its desired type.  Out-of-the-box
> >>> translators will include StringTranslator (includes a property to
> >>> determine whether an empty string will be interpreted as a null),
> >>> DateTranslator, and NumberTranslator (using
> >>> java.text.DecimalFormat).  TextArea's translator parameter will
> >>> default to a StringTranslator.  DatePicker's translator will default
> >>> to a DateTranslator.  Although TextField's translator will default
> >>> to StringTranslator, it value parameter will bind to an Object
> >>> (formerly value was bound to a String) so that it can use any
> >>> translator.  If the Translator fails to translate the submitted
> >>> text, then a validation error is recording and rewinding of the
> >>> component is finished.
> >>>
> >>     I think that implementing a translator is a great idea, because
> >> many time you need your values displayed differently as the way they
> >> are stored in the model.  But maybe the translator needs to be like a
> >> java.text.Format, the only bad things about the Format interface is
> >> that it is not very simple to implement and that is only one way.
> >> Thus using translator that can format data from the model to the view
> >> and then from the view to the model is a great idea, i would see it
> >> like cocoa translators if you know what i mean.
> >>
> > The Translator interface is used for both String to Object translation
> > (rewind) and Object to String translation (render).  Both the
> > NumberTranslator and DateTranslator will be java.text.Format-based
> > (using DecimalFormat and SimpleDateFormat, respectively).
> >
> >>> 3. "validators" - (a single Validator or list of Validators) a new
> >>> simplified Validator interface will be responsible for validating
> >>> the translated value (not the submitted text).  By making the
> >>> validators fine-grained, and by allowing multiple validators to be
> >>> used per field, we eliminate some more of the redundancy that exists
> >>> currently.  Out-of-the-box validators will include StringValidator
> >>> (maxLength, minLength), EmailValidator, RegExValidator,
> >>> EqualsValidator, and ComparableValidator (max, min).  If the
> >>> Validator fails to validate the translated value, then a validation
> >>> error is recording and rewinding of the component is finished.
> >>>
> >>> Consequently:
> >>> a. The old IValidator interface can be deprecated.
> >>> b. ValidField can be deprecated since it functionality is completely
> >>> achievable via the beefed up TextField.
> >>>
> >>> In Howard's blog, he suggests a new validator binding:
> >>> <binding name="validator"
> >>> value="validator:string,required,minLength=3"/>
> >>>
> >>> Essentially, this is what I described above (i.e. the 3 validator
> >>> responsibilities) except that it's all smushed into a single
> >>> parameter.  I think the smushed representation is too cluttered.
> >>> Especially since the translator part (e.g. string) will use a most
> >>> often use a default value.  I sort of like the idea of defining a
> >>> validator inline (e.g. minLength=3), but I think it will get too
> >>> messy and complex, especially when I want to use custom (i.e.
> >>> non-framework) validator implementations.
> >>
> >>
> >>    I agree that defining inline validator might not be the best, as
> >> when you want to define a custom validator it will be a completely
> >> different way to put it in the component.  I like the method of
> >> Howard because it is convenient for most simple case and that should
> >> be the default.  But as Howard said, in Tapestry 4 you can define new
> >> prefix, thus we can define a prefix for simple validation syntax
> >> 'value="validator:string,required,minLength=3"' and a prefix for
> >> backward compatible validator.  I think validation rules should not
> >> be tied to a field as in your suggestion, because a validation rule
> >> is tied to the logic of a form and not to the logic of a component,
> >> thus we would need to implement a new mechanism independent of per
> >> component validation but dependant of per form validation.  The other
> >> point is that most complex form validation are conditional, not all
> >> validation rule should be interpreted, validation rules should be
> >> interpreted only if a special condition is verified.  So maybe using
> >> your proposition of equal/comparable validator we should add a non
> >> mandatory property to the component that would be
> >> 'validatorCondition="myOtherComp.value == true"' if the condition is
> >> not verified then the validator should not display any error or
> >> should not be used.
> >>
> > Can you elaborate on what you mean be per form validation?  Why would
> > you not want to associate a validator with a field?  Can't cross-field
> > (i.e. per form) validation always be performed on the last field in
> > the validation set?
> > Since "validators" will already be an optional parameter (currently,
> > this is not the case with ValidField), there's no real need for an
> > additional parameter to toggle it (although I admit it might make
> > things easier to read):
> > e.g.
> > <bean name="someValidator" class="..."/>
> > <component id="someField" type="TextField">
> >    <!-- ... -->
> >    <binding name="validators" value="someCondition ?
> > beans.someValidator : null"/>
> > </component>
> >
>    Ok, i see your point, and i must say you convince me.  This is a
> clean approach. Does someCondition is evaluated at rewind time ?  Most
> often condition will be based on form input.  The only point that might
> be complicated is involving javascript validation.  This way, it would
> be hard te create javascript validation (i might be mistaken).  Or an
> option is that validators would have a method that one could override
> to generate the javascript for this validator.  The method would take
> in argument the html field names generated by tapestry and would return
> a javascript snippet with a message.  This snippet could then be
> incorporated in a main javascript 'validate_myForm()' function.  Maybe
> even better, instead of a function we would define a ".script" file
> with its argument being a list of fields and their type (checkbox,
> textarea, input text etc..), and thus generate a javascript snippet
> that will be added to the main javascript validation function.  I don't
> if i am very clear on this one?!
> The only problem with my proposal is then how do you integrate the
> someCondition in the javascript snippet generation as it is decoupled
> from the validator?
>
>
> >>
> >>
> >>>
> >>>> - 3 Multi component validation: I think it is possible to do a
> >>>> multi component validation using the Java Comparable interface, if
> >>>> the component implements the Comparable interface or delegate it to
> >>>> the validator  then we could compare components between them an
> >>>> write an expression this way i:
> >>>> Suppose We have a check box, and two text fields component in the
> >>>> page
> >>>> <validationRule>
> >>>> <condition>myCheckbox == true </condition> //condition for this
> >>>> rule to be evaluated
> >>>> <rule> passwd1 != passwd2 </rule> // rule to be evaluated
> >>>> <message>For new customers the password 1 and the password 2 must
> >>>> be the same </message> // validation message to be displayed
> >>>> </validationRule>
> >>>> A special helper object would be used to interpret and verify the
> >>>> rule, the object would read this rule and interpret it as follow,
> >>>> get the value of myCheckbox component and verify if it si true then
> >>>> get the value of passwd1 field and compare it for equality to the
> >>>> value of passwd2.  We could use OGNL to do this. OGNL will
> >>>> interpret the ==, <, >, != using compare and equals, the components
> >>>> should override the equal and compare function to forward it to its
> >>>> value, thus calling passwd1 != passwd2 will be transformed in "if
> >>>> (!passwd1.equals(passwd1))" and the equals will be overwritten as
> >>>> follow:
> >>>> public boolean equals(Object other) {
> >>>>     if (!(other instanceof IFormComponent)) {
> >>>>         throw Exception();
> >>>>     }
> >>>>     Object thisValue = this.getValue();
> >>>>     Object otherValue = other.getValue();
> >>>>     return    thisValue.equals(otherValue);
> >>>> }
> >>>>
> >>>> The same would happen for the compareTo method, and if the value
> >>>> don't implement comparable then an exception should be thrown.  If
> >>>> the value are primitive then we make direct comparison of primitive
> >>>> value.
> >>>>
> >>> This is the intention of the EqualsValidator and ComparableValidator
> >>> mentioned above.  For instance, say I have a user registration page
> >>> where I ask the user to enter a password - typically a page will
> >>> show 2 text fields, the second being a "confirmation" that the user
> >>> didn't make a typing mistake when entering their password.  In this
> >>> scenario I would use an EqualsValidator to validate the equivalency
> >>> accross fields.  It might look roughly like the following (forgive
> >>> my inexperienced 4.0 syntax):
> >>>
> >>> <bean name="passwordValidator"
> >>> class="org.apache.tapestry.valid.StringValidator">
> >>>    <set name="minLength" value="6"/>
> >>>    <set name="maxLength" value="12"/>
> >>> </bean>
> >>> <bean name="patternValidator"
> >>> class="org.apache.tapestry.valid.PatternValidator">
> >>>    <set name="pattern" value="... some regular expression ..."/>
> >>> </bean>
> >>> <bean name="confirmPasswordValidator"
> >>> class="org.apache.tapestry.valid.EqualsValidator">
> >>>    <set name="value" value="ognl:user.password"/>
> >>> </bean>
> >>>
> >>> <property name="user"/>
> >>> <property name="confirmationPassword"/>
> >>>
> >>> <component id="password" type="TextField">
> >>>    <binding name="value" value="ognl:user.password"/>
> >>>    <binding name="label" value="Password"/>
> >>>    <binding name="required" value="true"/>
> >>>    <binding name="validators" value="{beans.passwordValidator,
> >>> beans.patternValidator}"/>
> >>> </component>
> >>> <component id="confirmPassword" type="TextField">
> >>>    <binding name="value" value="ognl:confirmPassword"/>
> >>>    <binding name="label" value="Confirmation Password"/>
> >>>    <binding name="required" value="true"/>
> >>>    <binding name="validators" value="bean:confirmPasswordValidator"/>
> >>> </component>
> >>>
> >>> Thoughts?
> >>>
> >>    The problem i see with this method is that beans are instantiated
> >> for the lifecycle of the page, thus the confirmPasswordValidator
> >> value will not be updated during the rewind of the page, and the
> >> value will be the same through multiple request...  Maybe to avoid
> >> this problem, the confirmPasswordValidator should not hold the value
> >> of the component but the name or a reference to the component.
> >>
> > Sorry, I should have specified lifecycle="none" for the
> > confirmPasswordValidator.  That works, no?
> > The other point to make is that validation (after it is decoupled from
> > translation) acts on your model, not fields.  That is why I compare
> > "user.password" instead "components.confirmPassword.value".  The
> > difference becomes clearer if the values were bound to numbers or
> > dates.
> >
> > Paul
> >
> >> Numa
> >>
> >>> Paul
> >>>
> >>>> The following scenario is quite simple, but we could name
> >>>> validationRules and thus validationRules could be dependant of the
> >>>> success of other validationRules.
> >>>> I don't really know if this is realistic, but it seems to me
> >>>> possible, the problem is i don't know yet enough about the
> >>>> internals of tapestry and the page specification parser.
> >>>> But to implement this solution i would see that we need to change
> >>>> the following things:
> >>>>     -  modify the page / component specification parser to add
> >>>> support for reading the validationRule (Page/component DTD)
> >>>>     -  add a helper bean that records the validation rule and their
> >>>> imbrication and interpret then during page rewinding
> >>>>     - All validField component or formComponent  should implement
> >>>> comparable and overwrite equals
> >>>>
> >>>> In my absolut dreams we could even imagine that the helper bean
> >>>> translate this rule in javascript. or that in the specification we
> >>>> provide a script snippet that performs the validation.
> >>>>
> >>>> Maybe i am dreaming eyes open ;)
> >>>>
> >>>> Please give me some feedback about this idea if you think it is
> >>>> positive or not so maybe i try to dig more inside tapestry.
> >>>>
> >>>> Kind Regards
> >>>>
> >>>> Numa
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> --------------------------------------------------------------------
> >>>> -
> >>>> To unsubscribe, e-mail: [hidden email]
> >>>> For additional commands, e-mail:
> >>>> [hidden email]
> >>>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [hidden email]
> >>> For additional commands, e-mail: [hidden email]
> >>>
> >>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [hidden email]
> >> For additional commands, e-mail: [hidden email]
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]