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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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: [EMAIL PROTECTED]
> > >>>> For additional commands, e-mail:
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>
> > >>>
> > >>> ---------------------------------------------------------------------
> > >>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >>> For additional commands, e-mail: [EMAIL PROTECTED]
> > >>>
> > >>>
> > >>
> > >>
> > >> ---------------------------------------------------------------------
> > >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >> For additional commands, e-mail: [EMAIL PROTECTED]
> > >>
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > For additional commands, e-mail: [EMAIL PROTECTED]
> > >
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
> >
>
> --
> 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]