*The following is from
http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified
. If you don't like this solution, I would be interested in your
thinking, Rick. If you are interested, I have a comprehensive solution
to everything to do with buttons and images. I am going to add to it,
but it is pretty well developed.
*
*This is an efficient way to end forever that pesky and recurrent
problem of how to use multiple image buttons in your forms. (N.B.:
This solution also works for non-image (submit) buttons by using
values like <input type="submit" name="add.x" value="add"> in the
submit button. Or, just use <input type="submit" name="button"
value="add"> for a different solution for <input type="submit">
versus <input type="image">)*
*Assume that you have code not unlike:*
<input type='image' name='update' src='change.gif'>
<input type='image' name='delete' src='nuke.gif'>
*or, in Struts' image tag:*
<html:image property='submit' src='change.gif'/>
<html:image property='delete' src='nuke.gif'/>
*Now, how do we know which image has been clicked? The answer has
been complicated and costly in the past. Here is a simple way to
achieve everything at a low cost and with great flexibility and
freedom.*
String button = null;
Enumeration enum = request.getParameterNames();
String parameterName = null;
while(enum.hasMoreElements()) {
parameterName = (String)enum.nextElement();
if(parameterName.endsWith(".x")) {
button = parameterName.substring(0,parameterName.indexOf('.'));
}
}
*There you go. /If you clicked the image with name='submit', then
the variable button will have the value "submit"./ I suggest that
you toss out the LookupDispatchActions, the ButtonCommands, etc.
This is a done deal. You can clearly seek other ways to ensure a bit
more safety. For example, the code works equally as well with
"submit.button" as it does with "submit". Elegant, no, eh? I use a
class that encapsulates this functionality as follows:** *
*public class ImageTagUtil {
public static String getName(HttpServletRequest request) {
String command = null;
String buttonValue = null;
Enumeration enum = request.getParameterNames();
while(enum.hasMoreElements()) {
buttonValue = (String)enum.nextElement();
if(buttonValue.endsWith(".x")) {
command = buttonValue.substring(0,buttonValue.indexOf('.'));
}
}
return command;
}
}
*
*Surprisingly, some people still prefer the way I used to do this. I
think they just like the plain fanciness of it all. For those
people, here is code that is less extensible, more coupled, heavier,
etc. This code is comparatively not as good, in my opinion. There is
a further use of button objects which requires that you create a
separate button object for each image button you use on an html
page. That solution is very heavy and significantly affects the
footprint of a struts page. /If/ you are going to use buttons,
/which, again, is not recommended/, I would suggest the following
more lightweight version, which creates and then nulls one button
object per request. The use of an inner class allows the necessary
communications between the action form and the button class. *
*public class AdminButtonForm
extends ActionForm {
protected CrackWillowButton button;
protected String command;
public CrackWillowButton getButton() {
if(button == null) {
this.button = new CrackWillowButton();
}
return button;
}
public String getCommand() {
String hold = command;
command = null;
return hold;
}
public void setCommand(String command) {
this.command = command;
}
public void reset() {
button = null;
}
public class CrackWillowButton {
private Integer x, y;
public static final String CREATE = "create";
public static final String RETRIEVE = "retrieve";
public static final String UPDATE = "update";
public static final String DELETE = "delete";
public static final String SUBMIT = "submit";
public CrackWillowButton() {
}
public CrackWillowButton getCreate() {
setCommand(this.CREATE);
return button;
}
public CrackWillowButton getRetrieve() {
setCommand(this.RETRIEVE);
return button;
}
public CrackWillowButton getUpdate() {
setCommand(this.UPDATE);
return button;
}
public CrackWillowButton getDelete() {
setCommand(this.DELETE);
return button;
}
public CrackWillowButton getSubmit() {
setCommand(this.SUBMIT);
return button;
}
public void setX(Integer x) {
if(y != null) {
reset();
} else {
this.x = x;
}
}
public void setY(Integer y) {
if(x != null) {
reset();
} else {
this.y = y;
}
}
}
}
*
*So, don't use buttons, but just mine the value of the [name].x
request parameter. *
*Michael McGrady Cap't of the Eh Team*
Anyway, looking forward to you thinking on this.
Michael
Rick Reumann wrote:
Not sure which list this question/topic really belongs on so posting
to both. (I'm bringing it up on the dev list because I'm thinking
maybe the base MappingDispatchAction could/should be modified).
Some design background. I like to keep related tasks belonging in one
Dispatch Action class (flavor to be discussed). This is a typical
approach, yet one of the problems is desided on the type of
DispatchAction ... keep it DispatchAction or use one of the subclasses
LookupDispatch or MappingDispatch.
First off I really don't like the LookupDispatchAction. I've used it
extensively in a large application and it becomes a real pain. It
becomes really ugly to use when you start having some generic button
names that you reuse for different things. For example a changing
requirment was that we ended up having to use a button called "Ok" a
lot (I know stupid). So sometimes "Ok" would submit to the same
LookupDispatchAction but would need to access different methods. You
end up then having to create 'fake' button names in your resources
file just so the LookupDispatchAction can work correctly. Maintenance
of the LookupDispatch can be a pain also. Anyway...
Until the MappingDispatchAction, I've been relatively content with
using a standard DispathAction. What I like about the
MappingDispatchAction is that it works really nicely for links - you
don't have to append a dispatch parameter name to the URL. It's also
nice for typical forms since you don't have to provide a hidden
dispatch parameter on the page.
The only problem I'm running into it is when you have a form with more
than one button and each button should call a different dispatch
method. I haven't really figured out a good way to work this out with
the MappingDispatchAction. I think trying to change the form's action
attribute using JavaScript will be ugly (assuming it can even be done,
I've never tried it). The only solution I can think of at the moment
would be to override the getMethodName method of MappingDispatch and
provide an extra mapping in your config where the parameter would
change to something like parameter="dispatchMethod"
The overridden getMethodName might look like
protected String getMethodName(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response,
String parameter)
throws Exception {
if( "dispatchMethod".equals( parameter ) {
parameter = request.getParameter(parameter);
}
return parameter
}
This would allow you to use the MappingDispatchAction like a
DispatchActoin when needed. The only caveat is you would have to make
sure the if statement in the above is what you wanted. (Probably
better to pull the parameter name "dispatchMethod" from a properties
file or constants class).
Maybe there is a much better way to accomplish what I'm concerned with?
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]