You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Erik Weber <er...@mindspring.com> on 2004/07/17 07:30:20 UTC
Question on parameterizing action attribute to html:form
I want to use c:choose to decide how to set the value of the action
parameter in an html:form tag (add or update).
How exactly do I refer to the variable that is set in the c:when and
c:otherwise conditionals from within my html:action tag?
The only thing I can think of that works is something like this:
<html:form action="<%= someVar %>" . . . >
So how do I declare someVar, with c:set? Or do I have to use Scriptlet
or JSP declaration syntax?
Erik
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Question on parameterizing action attribute to html:form
Posted by Rick Reumann <st...@reumann.net>.
Andrey Rogov wrote:
> there is another way to work with parameter form:action. If you use
> Tiles in your applications create one reusable tiles lay with elements of
> design, control buttons and page control. In this case you can use the page
> with many forms. Then solution <html:form action="${myFormBean.the_action_URI}"/>
> can be replaced with <html:form action="${ControlBean.the_action_URI}"/> .
>
> What do you think ?
Sure that could work (using Tiles or Sitemesh), but I'm not sure you
gain that much by having a tile/include contain a header <htm:form
action="${ControlBean.the_action_URI}"/> on it versus <html:form
action="${myFormBean.the_action_URI}"/>. I probably wouldn't make a
whole seperate tile just for the html:form header.
Most of the time I don't need to dynamically change the action name
since the reusable form usually always has the same validation rules (an
update versus and add for me usually has the same data on the page..
sometimes hidden though). I also find it easier to understand when you
can quickly look at the JSP and see the action name delcared in the form
element.
Since I'm now leaning towards manually calling the validate methods
anyway (to avoid those issues of having to repopulate lists when
validation fails), I can always create custom validation calls based on
whether I'm doing an update versus an insert if I need to. This why the
Action name always remains the same on the form.
Obviously many ways to skin a cat here. I tend to avoid having dynamic
action names since some time a year later someone will say "When I'm on
such and such a page and click submit, I'm getting this wierd error." To
track down the problem it's easy then to just look at the JSP and see
the action it's submitting to. When it's dynamic it's a bit more of a
pain to track down what is going on.
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re[2]: Question on parameterizing action attribute to html:form
Posted by Andrey Rogov <an...@ukrpost.net>.
Hi Rick,
there is another way to work with parameter form:action. If you use
Tiles in your applications create one reusable tiles lay with elements of
design, control buttons and page control. In this case you can use the page
with many forms. Then solution <html:form action="${myFormBean.the_action_URI}"/>
can be replaced with <html:form action="${ControlBean.the_action_URI}"/> .
What do you think ?
( Your lessons still the best ).
Andrey .
RR> Erik Weber wrote:
>> if you have a single JSP
>> that houses a form that is used for different commands (add, update),
>> you are still going to need two separate form elements in
>> validation.xml, causing redundancy (until "field inheritance" is
>> implemented at least), correct?
RR> That is correct, although if you are using the "trick" way I mentioned
RR> you could "sort" of get around this by setting up a
RR> "baseEmployeeValidation" in your valiation.xml that you know will be
RR> common amongst all the particular forms in question. Then you can create
RR> a couple sub ones for the specifics (ie = "updateEmployeeValidation",
RR> "insertEmployeeValiation"). Then, since you are calling the validation
RR> manually you simply call the baseEmployeeValidation and then the
RR> appropriate custom valiation in your action. I haven't tried this, but
RR> it should work.
RR> Although I just took a brief look at the API and I'm not sure if you
RR> call validate() more than once if you end up with a new Instance of the
RR> ValidationResults being set to the ValidationForm's instance of
RR> "validatorResults." If it reuses the same instance and just adds on to
RR> the map then that would be cool. If not, then the best you could do with
RR> this trick would be to call the base common validation and if no errors
RR> return then proceed on to validate the next custom validation. The
RR> drawback to this is say the user completes a large form and submits.
RR> It's possible he'll get a validation error saying "something is wrong"
RR> and then he could submit after fixing it and get a new error (based on
RR> the custom portion). Sort of annoying because it should come back all at
RR> once. Anyway an attempt at this might look like: (not tested at all)...
RR> validate(..) {
RR> ServletContext application = getServlet().getServletContext();
RR> ActionErrors errors = new ActionErrors();
RR> String parameter = request.getParameter( mapping.getParameter() );
RR> //set up Validator and test the base stuff common to both the add
RR> //update. Remember, we know the name of the base Validation..
RR> Validator validator = Resources.initValidator( "baseEmployeeValiation",
RR> this, application, request, errors, page);
RR> try {
RR> validatorResults = validator.validate();
RR> } catch (ValidatorException e) {
RR> log.error(e.getMessage(), e);
RR> }
RR> //you might in the above also be able to test this custom
RR> //stuff, just haven't looked at how validator.validate() deals
RR> //with validatorResults if validate is called more than once
RR> //parameter would be your dispatch parameter represening the
RR> //"custom" unique part that needs validation..ie "addEmployee"
RR> //or "updateEmployee"
RR> if ( validatorResults.isEmpty() ) { //no errors from the base test
RR> validator = Resources.initValidator( parameter, this, application,
RR> request, errors, page);
RR> try {
RR> validatorResults = validator.validate();
RR> } catch (ValidatorException e) {
RR> log.error(e.getMessage(), e);
RR> }
RR> }
RR> return errors;
RR> }
RR> Probably easier just to delcare the two different validations in the xml
RR> and copy and paste the common validations into both:) Extends sure would
RR> be nice.
--
Best regards,
Andrey mailto:andrey.rogov@ukrpost.net
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Question on parameterizing action attribute to html:form
Posted by Rick Reumann <st...@reumann.net>.
Erik Weber wrote:
> if you have a single JSP
> that houses a form that is used for different commands (add, update),
> you are still going to need two separate form elements in
> validation.xml, causing redundancy (until "field inheritance" is
> implemented at least), correct?
That is correct, although if you are using the "trick" way I mentioned
you could "sort" of get around this by setting up a
"baseEmployeeValidation" in your valiation.xml that you know will be
common amongst all the particular forms in question. Then you can create
a couple sub ones for the specifics (ie = "updateEmployeeValidation",
"insertEmployeeValiation"). Then, since you are calling the validation
manually you simply call the baseEmployeeValidation and then the
appropriate custom valiation in your action. I haven't tried this, but
it should work.
Although I just took a brief look at the API and I'm not sure if you
call validate() more than once if you end up with a new Instance of the
ValidationResults being set to the ValidationForm's instance of
"validatorResults." If it reuses the same instance and just adds on to
the map then that would be cool. If not, then the best you could do with
this trick would be to call the base common validation and if no errors
return then proceed on to validate the next custom validation. The
drawback to this is say the user completes a large form and submits.
It's possible he'll get a validation error saying "something is wrong"
and then he could submit after fixing it and get a new error (based on
the custom portion). Sort of annoying because it should come back all at
once. Anyway an attempt at this might look like: (not tested at all)...
validate(..) {
ServletContext application = getServlet().getServletContext();
ActionErrors errors = new ActionErrors();
String parameter = request.getParameter( mapping.getParameter() );
//set up Validator and test the base stuff common to both the add
//update. Remember, we know the name of the base Validation..
Validator validator = Resources.initValidator( "baseEmployeeValiation",
this, application, request, errors, page);
try {
validatorResults = validator.validate();
} catch (ValidatorException e) {
log.error(e.getMessage(), e);
}
//you might in the above also be able to test this custom
//stuff, just haven't looked at how validator.validate() deals
//with validatorResults if validate is called more than once
//parameter would be your dispatch parameter represening the
//"custom" unique part that needs validation..ie "addEmployee"
//or "updateEmployee"
if ( validatorResults.isEmpty() ) { //no errors from the base test
validator = Resources.initValidator( parameter, this, application,
request, errors, page);
try {
validatorResults = validator.validate();
} catch (ValidatorException e) {
log.error(e.getMessage(), e);
}
}
return errors;
}
Probably easier just to delcare the two different validations in the xml
and copy and paste the common validations into both:) Extends sure would
be nice.
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Question on parameterizing action attribute to html:form
Posted by Erik Weber <er...@mindspring.com>.
Rick, thank you for your thoughtfulness and generosity.
You made me realize that I can set the form action URI as a form bean
attribute in my setup Action class, and then, instead of implementing a
c:choose switch on a "command" request attribute in my JSP to set the
form action URI, I can just use:
<html:form action="${myFormBean.the_action_URI}"/> as you suggested.
Yes, I do need to parameterize this URI for the sake of the form
validator plugin (as far as I know). But you have improved my code --
tentatively as I haven't actually gotten to this yet :-)
I am not using the MappingDispatchAction as I cannot go to 1.2 yet, but
it will be easy to upgrade to it, as I am setting the "parameter"
attribute in my action mappings in required fashion. But for now I am
simply using an if-else construct that uses String.equals with this
parameter to decide which "command" to execute in my Action class (it
extends ValidatorAction).
Also, the "trick" you describe below to manually invoke the Validator
plugin via a form bean's validate method is clever and useful indeed. I
may try that, and definitely will in the case of multiple submit
buttons. But still, even with this technique, if you have a single JSP
that houses a form that is used for different commands (add, update),
you are still going to need two separate form elements in
validation.xml, causing redundancy (until "field inheritance" is
implemented at least), correct?
Thanks again for your help,
Erik
Rick Reumann wrote:
> Erik Weber wrote:
>
>> I found the answer. It is to use the struts-el html tag library
>> instead of the standard html tag library, and then to refer to the
>> variable using the expression language syntx:
>>
>> <c:set var="action" value="/foo/update"/>
>>
>> . . .
>>
>> <html:form action="${action}" . . . />
>
>
> Erik are you uisng one of the DispatchActions (regular DispatchAction,
> LookUpDipsatcchAction, in 1.2 MappingDispatchAction)? In these cases
> you could reuse ONE mapping to accomplish your different common tasks
> and won't need to change the form Action name.
>
> For example, say you were dealing with updating, inderting, viewing
> Employee information. I would make one DispatchAction called
> "EmployeeDispatchAction" and in there you'd you have your different
> methods:
>
> update(..), retrieve(..), maybe even getListOfEmployees(..), etc.
>
> Then your form mapping would simply be something like
> 'employeeAction', which would result in
>
> <html:form action="employeeAction"> <--- no need for dynamically
> changing the action attribute
>
> What method gets called inisde of EmployeeDispatchAction is based on
> the parameter you decide to use (I like to call mine "userAction"). So
> if using the LookupDispatchAction I have a hidden variable which is
> set to this variable:
>
> <html:hidden property="userAction"/>
>
> The nice thing is you also shouldn't need to do any logic on JSP
> either for this, since you can set the "userAction" BEFORE you get to
> the page in the Action you are coming from (always go through an
> action:). So for example you click on a menu link called "update
> employee" - before bringing you to the update employee page you'd
> first go through a SetUp method in an action and since you know you
> are then proceding on to the "update" page you simply set the form
> variable...
>
> myForm.setUserAction(Constants.UPDATE) or
> myForm.setUserAction("update") or if DynaForm:
> myForm.set("userAction","update"); or use a Constants.UPDATE
>
> Now I think I remember an earlier discussion where different
> validations (using the same form) were an issue. In that case having
> separate action names could be helpful. But even there I'd key the
> action value based of the parameter for your dispatch action name (no
> need to do any set or loigic):
>
> <html:form action="${myFormBean.userAction}">
> ...
> </html:form>
>
>
> And another approach I've used before is a little awkward but it can
> come in handy and your JSP would even avoid the el above. You'd have
> one action name (ie action="employeeAction") and of course a dispatch
> parameter on the page somewhere and which is defined in the action
> mapping (ie parameter="userAction"). Then you can simply call your
> form bean's validate method manually. Your formBean would have an
> over-ridden validate method and it can call the appropriate validator
> based on the dispatch parameter. It came in handy for a case where I
> had different submit buttons on one form and depending on which one
> was selected I had to validate differently. I found it pretty clean.
> If you ever go this route here's an example...
>
> validation.xml:
>
> <form name="displayFromIndiIds">
> <field property="cardStartId"
> depends="required,integer">
> <arg0 key="gc.cardStartId.displayname"/>
> </field>
> ...
>
> FormBean with over-riden validate:
>
> validate(..) {
> ServletContext application = getServlet().getServletContext();
> ActionErrors errors = new ActionErrors();
> String parameter = request.getParameter( mapping.getParameter() );
> //parameter would be your dispatch parameter ie displayFromIndiIds
> Validator validator = Resources.initValidator( parameter, this,
> application, request, errors, page);
> try {
> validatorResults = validator.validate();
> } catch (ValidatorException e) {
> log.error(e.getMessage(), e);
> }
> return errors;
> }
>
>
>
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Question on parameterizing action attribute to html:form
Posted by Rick Reumann <st...@reumann.net>.
Erik Weber wrote:
> I found the answer. It is to use the struts-el html tag library instead
> of the standard html tag library, and then to refer to the variable
> using the expression language syntx:
>
> <c:set var="action" value="/foo/update"/>
>
> . . .
>
> <html:form action="${action}" . . . />
Erik are you uisng one of the DispatchActions (regular DispatchAction,
LookUpDipsatcchAction, in 1.2 MappingDispatchAction)? In these cases you
could reuse ONE mapping to accomplish your different common tasks and
won't need to change the form Action name.
For example, say you were dealing with updating, inderting, viewing
Employee information. I would make one DispatchAction called
"EmployeeDispatchAction" and in there you'd you have your different methods:
update(..), retrieve(..), maybe even getListOfEmployees(..), etc.
Then your form mapping would simply be something like 'employeeAction',
which would result in
<html:form action="employeeAction"> <--- no need for dynamically
changing the action attribute
What method gets called inisde of EmployeeDispatchAction is based on the
parameter you decide to use (I like to call mine "userAction"). So if
using the LookupDispatchAction I have a hidden variable which is set to
this variable:
<html:hidden property="userAction"/>
The nice thing is you also shouldn't need to do any logic on JSP either
for this, since you can set the "userAction" BEFORE you get to the page
in the Action you are coming from (always go through an action:). So
for example you click on a menu link called "update employee" - before
bringing you to the update employee page you'd first go through a SetUp
method in an action and since you know you are then proceding on to the
"update" page you simply set the form variable...
myForm.setUserAction(Constants.UPDATE) or
myForm.setUserAction("update") or if DynaForm:
myForm.set("userAction","update"); or use a Constants.UPDATE
Now I think I remember an earlier discussion where different validations
(using the same form) were an issue. In that case having separate action
names could be helpful. But even there I'd key the action value based of
the parameter for your dispatch action name (no need to do any set or
loigic):
<html:form action="${myFormBean.userAction}">
...
</html:form>
And another approach I've used before is a little awkward but it can
come in handy and your JSP would even avoid the el above. You'd have one
action name (ie action="employeeAction") and of course a dispatch
parameter on the page somewhere and which is defined in the action
mapping (ie parameter="userAction"). Then you can simply call your form
bean's validate method manually. Your formBean would have an over-ridden
validate method and it can call the appropriate validator based on the
dispatch parameter. It came in handy for a case where I had different
submit buttons on one form and depending on which one was selected I had
to validate differently. I found it pretty clean. If you ever go this
route here's an example...
validation.xml:
<form name="displayFromIndiIds">
<field property="cardStartId"
depends="required,integer">
<arg0 key="gc.cardStartId.displayname"/>
</field>
...
FormBean with over-riden validate:
validate(..) {
ServletContext application = getServlet().getServletContext();
ActionErrors errors = new ActionErrors();
String parameter = request.getParameter( mapping.getParameter() );
//parameter would be your dispatch parameter ie displayFromIndiIds
Validator validator = Resources.initValidator( parameter, this,
application, request, errors, page);
try {
validatorResults = validator.validate();
} catch (ValidatorException e) {
log.error(e.getMessage(), e);
}
return errors;
}
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Question on parameterizing action attribute to html:form
Posted by Erik Weber <er...@mindspring.com>.
I found the answer. It is to use the struts-el html tag library instead
of the standard html tag library, and then to refer to the variable
using the expression language syntx:
<c:set var="action" value="/foo/update"/>
. . .
<html:form action="${action}" . . . />
Erik Weber wrote:
> I want to use c:choose to decide how to set the value of the action
> parameter in an html:form tag (add or update).
>
> How exactly do I refer to the variable that is set in the c:when and
> c:otherwise conditionals from within my html:action tag?
>
> The only thing I can think of that works is something like this:
>
> <html:form action="<%= someVar %>" . . . >
>
> So how do I declare someVar, with c:set? Or do I have to use Scriptlet
> or JSP declaration syntax?
>
> Erik
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org