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]



Reply via email to