I described what I wanted to achieve in my original posting. To recap, I want to have a page with several delete buttons. Clicking on one button would produce parameter
delete_23.x=56
to be sent => we parse that, and delete item with ID 23 from database. Choosing a different delete -button would send parameter
delete_304.x=144
=> we delete item with ID 304.
I am aware that I can use the approach you suggested (parse request parameters manually), and have been doing that for ages before I started learning Struts :) I was just expecting that Struts would somehow help me with this task. I have been looking into indexed properties but I have not quite figured out how to properly implement this kind of functionality using them.
I finally figured out a reasonably satisfying way to do this while using Struts to help as much as possible:
public class ChoicesForm extends ActionForm {
private Collection choices; private ImageButtonTracer deleteButton;
public void reset(ActionMapping arg0, HttpServletRequest arg1) { this.choices = new ArrayList(); this.deleteButton = new ImageButtonTracer(); }
public ChoiceView getChoice(int index) { // if struts tries to get item with id index, // and it does not exist, // add new items until ok. while (choices.size() <= index) { choices.add(new ChoiceView()); } List lChoices = (List) choices; return (ChoiceView) lChoices.get(index); }
public Collection getChoices() { return choices; } public void setChoices(Collection collection) { choices = collection; } public ImageButtonTracer getDeleteButton() { return deleteButton; } public void setDeleteButton(ImageButtonTracer tracer) { deleteButton = tracer; } }
public class ImageButtonTracer { private Map clickedButtons;
public ImageButtonTracer() { clickedButtons = new HashMap(); }
public Button getItem(int index) { Button toReturn = (Button) clickedButtons.get(new Integer(index)); if (toReturn == null) toReturn = new Button(); clickedButtons.put(new Integer(index), toReturn); return toReturn; }
public void setItem(int index, Button button) { logger.debug("setItem(" + index + ")"); clickedButtons.put(new Integer(index), button); }
public Collection getClickedButtonIndexes() { return clickedButtons.keySet(); }
public class Button { private int x; private int y;
public int getX() { return x; } public int getY() { return y; } public void setX(int i) { x = i; } public void setY(int i) { y = i; } } }
public class ChoiceView implements Serializable { private String key; private String name; private String description;
... + getters & setters }
<html:form action="/SaveChoices" method="GET">
<table border=1>
<logic:iterate id="choice" name="choicesForm" property="choices">
<tr>
<td><bean:write name="choice" property="key"/><html:hidden indexed="true" name="choice" property="key"/></td>
<td><html:text indexed="true" name="choice" property="name"/></td>
<td><html:text indexed="true" name="choice" property="description"/></td>
<td><html:image indexed="true" src="delete.gif" property="deleteButton.item"/></td>
</tr>
</logic:iterate>
</table>
<br><html:submit/>
</html:form>
public class SaveChoicesAction extends Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ChoicesForm cform = (ChoicesForm) form;
ChoiceDAO dao = new ChoiceDAO(); // UPDATE Iterator i = cform.getChoices().iterator(); while (i.hasNext()) { ChoiceView view = (ChoiceView) i.next(); Choice toUpdate = ChoiceView.createChoice(view); dao.update(toUpdate); }
// DELETE Collection deletedIds = cform.getDeleteButton().getClickedButtonIndexes(); if (deletedIds != null) { Iterator d = deletedIds.iterator(); while (d.hasNext()) { int deleteIndex = ((Integer) d.next()).intValue(); ChoiceView toDelete = cform.getChoice(deleteIndex); Choice choice = ChoiceView.createChoice(toDelete); dao.delete(choice); } } return mapping.findForward("success"); } }
ImageButtonTracer can be simplified a bit if one assumes that only one button can be clicked per request (as is the case) => public Collection getClickedButtonIndexes() can be changed to public int getClickedButtonIndex(). This works, and I can use indexed properties somewhat comfortably.
Any improvements / alternatives are welcome.
_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]