Matthias Kahlau wrote:
Hi!
Some questions regarding validator methods (using "validator "attribute of
components):
1) In which phase are these methods invoked? Always in process validations
or dependent on immediate setting?
In the "decode" part of the "apply-values" phase when the component is
immediate.
In "validate" phase otherwise.
2) Which is the right method to get the values of other components in the
validator method, getSubmittedValue(), getLocalValue(), dependent on
configuration issues (immediate) of the component owning the validator and
other components asked in the validator method?
Hmm. You're trying to implement "cross-component" validation I presume?
I've not tried to do this myself, but as I have spent some time recently
getting familiar with the validation process here's what I think will
happen....
When the validator's component has immediate=false:
===================================================
All other components will have performed "decode", ie set their
submittedValue from the input request params.
Components occurring *before* the component associated with the
validator which have *valid* input will have converted the data, stored
it in localValue, then run the validators. Such components will
therefore have localValue set, and submittedValue=null. Their "isValid"
method will return true.
Components occurring *before* the component associated with the
validator whose *convert* operation failed will have the "new" value
left in submittedValue. But in this case, you'll probably not be able to
do your cross-component validation anyway, as all that's available to
you is the raw unconverted submittedValue. Such components will have
isValid return false.
Components occurring *before* the component associated with the
validator whose *convert* operation succeeded but validate failed will
have the "new" value left in localValue. But in this case, you'll
probably not want to do your cross-component validation anyway, as the
component is already known to be invalid. Such components will have
isValid return false.
Components occurring *after* the component associated with the validator
but which are not immediate will have set their submittedValue but not
tried to convert/validate. Therefore only the submittedValue is
available. And unfortunately isValid will return true.
Components that are declared "immediate" will have already performed
decode, convert, validate. So they act just like components occurring
"before" the validator's component, regardless of where they actually
occur in the page.
I would therefore suggest:
(a) always put your cross-component validator on the last component
involved in the check
(b) check for other.submittedValue != null ==> don't bother validating,
as the input value couldn't be converted
(c) check for !other.isValid ==> don't bother validating, as the
component is already invalid.
When the validator's component has immediate=false:
====================
The validate call will occur before other components have even tried to
decode their values from the http request. Cross-component validation is
therefore quite impossible at this time, unless validating against
components which are both earlier in the page *and* themselves immediate.
See also:
http://www.jsf-faq.com/faqs/faces-validation.html#133
There doesn't seem to be a good FAQ entry anywhere on implementing
cross-component validation, so maybe if you get this working it would be
a good idea to create a wiki HOWTO entry?
Cheers,
Simon