It seems like the main issue is how to submit both the _eventId
and account index using a single <button type='submit'/>
element?
Here is a great question & answers about exactly this issue: How do you overcome the html form nesting limitation?. Using a hidden input with the account index doesn't help because the submit button would submit all of the hidden inputs anyway.
Of course, you could use an anchor instead of a submit button as long as you didn't want to submit anything else, e.g.
<a href="${flowExecutionUrl}&_eventId=deleteItem&index=${v}">Delete This Item<a>
and
<transition on="deleteItem" bind="false" validate="false">
<evaluate expression="flowService.deleteItem(flowScope.myInfo, requestParameters.index)" result="flowScope.myInfo"/>
</transition>
but semantically, a "delete" operation shouldn't be an HTTP GET request. I tend to use an anchor anyway, because it seems like the least hacky alternative. But, after reading through the linked question, I see that there is an HTML5 alternative - the "formaction" attribute. In this case, the JSP would look something like this:
<form:form action="${flowExecutionUrl}" method="post" commandName="backingObject">
<c:forEach items="${myInfo.myList}" var="listItem" varStatus="status">
<form:input path="myInfo.myList[${status.index}]"/>
<button type="submit" name="index" value="${status.index}"
formaction="${flowExecutionUrl}&_eventId=deleteItem">
Delete This Item
</button>
</c:forEach>
</form:form>
Basically, the selected button overrides the enclosing form's 'action' attribute, to include the _eventId
parameter.
You'd need to consider the browser support, but maybe you can provide a javascript polyfill to support older browsers.
Side note
Since selecting an item from a list (for the purposes of deleting it, displaying it, whatever) is a very common use-case, I like to use a custom list class which allows you to bind the index to the list itself:
public class SelectionList<T> extends ArrayList<T> {
// the index of the selected item within the list
private Integer index;
public SelectionList() {
}
public SelectionList(Collection<? extends T> c) {
super(c);
}
// this is used for binding to/from the view layer, and shouldn't be called by application code
public Integer getIndex() {
return index;
}
// this is used for binding to/from the view layer, and shouldn't be called by application code
public void setIndex(Integer index) {
this.index = index;
}
// use this to retrieve the selected item from the list.
public T getSelectedItem() {
if (index == null || index >= super.size() || index < 0) {
return null;
}
return super.get(index);
}
}
Then, you could bind the selected index directly to the list and just call list.getSelectedItem()
after binding has occurred.