Are there any guidelines on writing a validator that validates multiple components (ex:city,state and zip are only required if the user enters an address)?
In the beta JSF 1.0 I was playing around with this and it seemed like I could get a component other than the one being validated from the tree and call getValue() to get the value for it. In the released version it seems like sometimes getValue returns the old value and sometimes the new.
The strategy you used (go retrieve the other component from the tree) is still the correct one.
One factor that affects whether you see the old or new value is when you call getValue(). For example, if you call it during the action method of an <h:commandButton> that has immediate="true", you will still see the old value, because conversion and validation does not occur until later on. If your command has immediate="false" (which is the default), you'll see the new value.
A new feature in the final release is that the "immediate" attribute has been added to all of the input components, as well as the command components. Therefore, if you do need to process the new value in an event handler for an immediate="true" command, simply set immediate="true" on the input value as well. This causes conversion and validation to occur during Apply Request Values phase, rather than waiting for Process Validations phase, for that particular component.
Re: Writing a validator that validates multiple components
Mar 8, 2004 11:24 AM
(reply 2
of 8) (In reply to
#1 )
I think from your response that a bug was introduced in the released version that wasn't in the beta then.
The code is being called from the validate method of a custom validator
public void validate(FacesContext arg0, UIComponent arg1, Object value) throws ValidatorException {
UIInput comp1=pull comp 1 from tree
UIInput comp2=pull comp 2 from tree
System.out.println(comp1.getValue());
System.out.println(comp2.getValue());
}
seems to always return the old value most of the time regardless of the what immediate=" " is set to. If I add this same validation to two components I get the following results, which really don't make any sense.
First Validator Output
old value for comp1
old value for comp2
Second Validator Output
new value for comp1
old value for comp2
Do you guys have a bugzilla or someplace else to report these things?
Re: Writing a validator that validates multiple components
Mar 8, 2004 1:15 PM
(reply 3
of 8) (In reply to
#2 )
No, it isn't a bug. The current behavior is as intended and specified.
What was happening in the beta is that getValue() would sometimes return the "submitted value", and other times return the actual, validated value. There was very little way to see which was which, so, for instance, you could get ClassCastExceptions if you tried to cast getValue() to an Integer when conversion from String to Integer had failed. In 1.0, the "submitted value" is stored with get/setSubmittedValue(), and the real value is stored using getValue(). But, this means that if you call getValue() too early, you'll get the old value, not the new value.
Again, this is all as intended. But it does mean that you need to be very careful about who you use multi-component validators. The "Second Validator Output" is what you want, except that you should be using the value passed to the validator instead of comp2.getValue().
Re: Writing a validator that validates multiple components
Mar 8, 2004 1:36 PM
(reply 4
of 8) (In reply to
#3 )
This brings me back to my initial question. What are the guidelines for writing a validator that can validate multiple components? Is there a way to have the validator fire after the value is set on all the components such that getValue() will always return the value to validate?
What is the best practice for getting values from the other components in a validator that works whenever the validate method fires? Otherwise, how can one write a generic validator that can be used throughout an application and also validate multiple components.
Re: Writing a validator that validates multiple components
Jul 8, 2004 12:25 AM
(reply 5
of 8) (In reply to
#4 )
This brings me back to my initial question. What are
the guidelines for writing a validator that can
validate multiple components?
Did you get any response on this?
I have a form with 3 input fields, S, A and E, and the constraint that either S and A has to be given a value and E not, or E has to be non-empty and the two others empty.
This validation should not be invoked on each of the components, rather on the form as such, after all components in the form have been updated with new values.
So may be what is missing is the ability to specify a validator on a commandButton tag, or on the form-tag itself?
And, of course, the ability to specify that validation should occur also on null-values.
IMO, this should be the responsibility of the Validator, so that enabling this would be a matter of overriding a method (something like ignoreNullValue()) in ones own Validator implementations.
As of the current design, it seems like the best solution for now is to employ form validation
in the client?
Re: Writing a validator that validates multiple components
Jul 8, 2004 6:54 PM
(reply 6
of 8) (In reply to
#5 )
Things to try:
Immediate attribute on one or more components (new attribute)
Phase Listener - this is pretty cool
JavaScript on the client side (button onClick)
custom component
The book "Core Java Server Face" has an excellent discussion of validation, including multiple field validation. It's available online at http://www.horstmann.com/corejsf
Basicallty the technique is to traverse the tree to find the value. But you can write custom validators and custom validator tags to be able to reuse your validation, and to make validation easy for your page designers to write.