See http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified


Janne Mattila wrote:

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]







--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to