OK, Cap't of the Eh Team!

Maybe you should go and add "Note: this is a clear, extensible, light, fast, loosely coupled, solution compared to a messy, solution specific, heavy, slow, tightly coupled version!" to the Wiki page? After all, you have invented an elegant solution with low cost and with great flexibility and freedom!


From: Michael McGrady <[EMAIL PROTECTED]>
Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]>
To: Struts Users Mailing List <[EMAIL PROTECTED]>
Subject: Re: Accessing bean properties problem
Date: Fri, 13 Aug 2004 07:11:29 -0700

No mas, Janne! If you think that your serpentine code is superior to the following:

public class ButtonMiner {
public int getId(HttpServletRequest request) {
String buttonValue = null;
Enumeration enum = request.getParameterNames();
String parameterName = null;
while(enum.hasMoreElements()) {
parameterName = (String)enum.nextElement();
if(parameterName.endsWith(".x")) {
buttonValue = parameterName.substring(0,parameterName.indexOf('.'));
}
return Integer.parseInt(buttonValue.substring(1));
}
}


which you could get from indexing "_", then go for it! I have no more to say.

Michael

Janne Mattila wrote:

I am well aware of the solution that you suggest and the fact that you think other solutions are over-engineered - I did indeed try to search for a solution before creating my own, and noticed the wiki page with the original over-engineered solution (which I noticed did change just recently).

There are two problems, first, your solution does not solve my case. Note that this is not a simple case of distinguishing whether "accept" or "nuke" was clicked (for those I would not certainly have used the original strategy from the wiki page, I agree with over-engineering there) - I want to get the ID conveniently as well. Please refer to earlier posts for details. Of course, I can add more parsing code to get also the ID, but this does not help with the second problem.

Which is: the purpose of Struts is to help me with some tasks, one important being parsing HttpServletRequest parameters so I do not have to deal with them manually. This service comes with a price - I have to spend time to learn the principles of the framework and all the small annoying quirks and unintuitive details (so far I've ran into quite a few!). If I have to both learn to cope with Struts and still continue to parse request parameters manually like I have done so many times before, the deal does not sound so good to me. The solution you suggest works, is not too complicated, but it does not integrate as seamlessly with the rest of the framework and how it is used to handle parameters. Button parameters end up being an exception to the general rule and I prefer a "pretty" solution. The solution I described also integrates nicely to the way other indexed properties are handled on the JSP page.

I don't know, but I am currently satisfied with the solution I am using. I end up creating one additional class (ImageButtonTracer) and add instance of it as a field to each form that requires this kind of "indexed buttons". You would probably create one additional helper class (with a further developed version of the method you present) and add parameter name encoding logic to each form that contains such buttons.


From: Michael McGrady <[EMAIL PROTECTED]>
Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]>
To: Struts Users Mailing List <[EMAIL PROTECTED]>
Subject: Re: Accessing bean properties problem
Date: Fri, 13 Aug 2004 05:57:24 -0700

This is all "over-engineered", Janne. I used to do something similar, however. As I menteioned before, I just use the following code to determine which image was clicked:

String imageClicked = null;
Enumeration enum = request.getParameterNames();
String parameterName = null;
while(enum.hasMoreElements()) {
parameterName = (String)enum.nextElement();
if(parameterName.endsWith(".x")) {
imageClicked = parameterName.substring(0,parameterName.indexOf('.'));
}
}
return imageClicked;


That's all there is to it. Your button solution is too complicated in any event. The better button solution involves making only one button and then nuking that button as soon as you determine what image was clicked. I just nuked the whole solution, since it is unnecessary.

Michael

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]


_________________________________________________________________
Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963



--------------------------------------------------------------------- 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]


_________________________________________________________________
The new MSN 8: advanced junk mail 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