struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Affonso <glis...@greywether.com>
Subject Re: Conditional Validation
Date Sun, 04 Nov 2007 05:40:20 GMT
naveen472-m@yahoo.co.in wrote:
> Can anyone tell me how to do conditional validation in struts 2?
> 
> In one form I want validations for a particular category (say Category XYZ) only if the
candidate in that. If he is NOT Category XYZ then by checking a checkbox he should be able
to skip the validations for that. I am not able find any solution to this problem. I guess
there are no provisions for conditional validation in Struts 2. Struts 1 had a <validwhen>
tag. But I am not able to find any equivalent tag for Struts 2.

This was true for WebWork, I'm assuming it remains true for s2...

If you're using the xml-based validation framework then you can use the 
"expression" validator to do validations on as many fields/conditions 
(and their combinations) as you want.

Here's an example:

     <validator type="expression">
         <param name="expression">
             ! (
                 ( chosenAddressId.intValue() eq -1 )
                 and
                 ( regionId.intValue() eq -1 )
                 and
                 ( ( countryId.intValue() eq 1 ) or ( 
countryId.intValue() eq 2 ) )
                )
         </param>
         <message>
If you choose to use a custom address and choose US or Canada as your 
country, you must choose a state/region from the drop-down menu.</message>
     </validator>

The HTML that the above code validates has three fields.  A radio button 
with a "custom" address choice, a country drop-down (select) and a 
state/region drop-down (the drop-downs have IDs for values).

The above validation says that a region choice is required if the user 
chooses the "custom address" radio button AND they choose US or Canada 
for the country drop-down.

Be warned, though.  Writing and debugging complex OGNL validation 
expressions absolutely sucks (IMO).  It's confusing to get the logic 
right (you'll notice that I've written the checks above as positive 
statements and then reversed the whole expression.  I find writing the 
checks in the negative to be way less intuitive) and very, very 
difficult to debug (hint, while developing these you can include field 
references in the message (I think it's a ${} syntax but I can't 
remember) to try to get some debugging info back out to yourself.)

Your other choices are...

1) Just do validation at the top of your Action's execute method.
Your Action's execute method gets called after all the interceptors have 
run.  Meaning that all the form values will have been applied to the 
Action's (or domain objects) properties.

So the first thing you do at the top of your execute method is a bunch 
of validity checks on those properties.  If those checks fail, you just 
some sort of message to the Action's FieldErrors/ActionErrors 
(addActionError, addFieldError, etc.) lists and return a 
failure-oriented result code (commonly INPUT).  Same end-result as if 
you'd used the xml framework.

(Note: I think actions get their fieldError and ActionError lists by 
sublclassing ActionSupport which implements validationAware.  So if your 
actions are not doing either you'll want to check that out.)

2) Implement the "validatable" interface
Not a whole lot different than the above but in this case you put your 
validation logic in a "validate" method in your action.

---

If you want to do the same validation for a domain object in several 
different actions, Webwork (and presumably s2) has the option to shift 
XML-based validation to be domain-object-based (instead of being 
action-based).  Basically you write a -validation.xml file for the 
*domain* object not each of the actions and then you tell the action to 
delegate the validation back to the domain object.  I've completely 
forgotten how to do this but if that interests you you should be able to 
find it in the docs easily enough.

In general, what you want to do (multi-field validation) is common, 
directly supported, and fairly easy.  You just need to pick which route 
you want to go.  I'd probably recommend doing this in the "validate" 
method.  You get to use java, and it's absolutely clear that this is 
"validation" logic (because it's in a dedicated validate method).

That is, I'd recommend it if you're OK tying your validation logic to 
the actions.  If you want validation logic you can share across more 
tiers of your application that's an entirely separate discussion.

WARNING: the above was true for WebWork (2.x).  Or mostly.  It's been 
awhile since I've looked at any of this in depth and I'm going from 
memory here.  (and right-before-bed memory at that).  But the above 
should be correct enough to get you headed in the right direction.

Good luck!

- Gary




:-)


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message