Trying to catch up some late reading (yep, nearly one week!), I found some questions related to early validation of widget values. Firstly, I fixed the problem (introduced just before 2.1.4 was released): validation occured at each and every readFromRequest(), which was obviously not the expected behaviour! From now on, we're back to validation being done only when validate() is called, and also on getValue().
I'm the one who introduced this validation on getValue(), but maybe not the way it should be. So let me explain where it came from and let's discuss it.
Type safety is an important feature of CForms: the application doesn't have to deal with strings sent in the request, but only with object types such as date and integers.
Now what about "value safety"? When writing some application code that relies on the form values (event listeners, binding, etc), widgets should return only correct values, i.e. values that are not only syntactically correct (according to the converter), but also semantically correct (according to the validators). Or else, we have the risk for the application to fail badly simply because it used incorrect values.
Now how do we solve this? A solution is that widget.getValue() not only does the parsing, but also the validation, and therefore returns a non-null value if and only if the input value is successfully parsed and validated.
This is what is done in Field, with the side effect that calling getValue() may set a validation error on the widget even if validate() wasn't explicitely called. This side effect is interesting: for example, if an event listener couldn't do its job because of a wrong input, the offending input is automatically shown to the user. This is examplified in the "number fields" section in the "flow1.form" sample.
Now this behaviour can also lead to premature flagging of widgets that may not be wanted. An example of this is in the carselector sample (see event listeners in the form definition) where we must reset the "make" widget value to null because a "getValue" can set a validation error if the user chose the null value.
So, although validation _must_ occur when getValue() is called, we may want getValidationError() to return null until validate() has actually been called.
So the two possible behaviours are:
- as of today (with the fix), have validation errors as the side effect of getting the value.
- raise the validation error only if validate() was called, even if getValue() does the actual call to the validators.
That second solution will require event-listeners to manually call validate() if ever they want to show errors on the widgets they act upon to the user.
What do you think?
Sylvain
-- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
