I'm using Webflow 2.3.2 in an application, and on one step the user can add/delete from a list in the bound model object (they simply return to the current step after the modification). For example my object might look like this:
public class MyInfo implements Serializable {
List<String> myList = new ArrayList<String>();
}
Doing the "add" in webflow is no problem because I simply stick the new object on the end of the list, but for the "delete" I need to identify the element to delete. What I'm doing now is using the "currentEvent" predefined EL object and grabbing the raw event "value" which I've populated with the ID of the record to delete. I'm wondering if there's a more elegant way to do this, because this seems like going the long way around. Can anyone suggest a better way of doing this? Here's an illustration of what I'm doing now:
My JSP file (note the "delete" button):
<c:forEach items="${myInfo.myList}" var="listItem" varStatus="listItemStatus">
<c:set var="v" value="${listItemStatus.index}"/>
<div><form:input id="listItemValue_${v}" path="myInfo.myList[${v}]"/></div>
<div><button id="deleteItem_${v}" name="_eventId_deleteItem" type="submit" value="${v}">Delete This Item</button></div>
</c:forEach>
My "flow.xml" file:
<transition on="deleteItem" bind="false" validate="false">
<evaluate expression="flowService.deleteItem(flowScope.myInfo, currentEvent.attributes)" result="flowScope.myInfo" />
</transition>
My event handler:
public MyInfo deleteAccount(MyInfo myInfo, LocalAttributeMap currentEvent) {
myInfo.getMyList().remove(Integer.valueOf((String)(currentEvent.asMap().get("_eventId_deleteItem"))).intValue());
return myInfo;
}
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>
andbut 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:
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:
Then, you could bind the selected index directly to the list and just call
list.getSelectedItem()
after binding has occurred.you can use a parameter in your submit to send your index:
and then:
finally: