Have multiple submit buttons in a form and determine which was pressed in a controller
In my Spring application, I have a jsp that has a form where I want to have multiple submit buttons that go to the same controller. I need to be able to determine which button was pressed in the controller. The form displays a number of items to the user and they can select one of the items with the only difference being the ID of the selected item.
In the jsp, I'm creating the form like this:
<form:form method="post" commandName="myCommand">
<c:forEach items="${model.availableitems}" var="item">
<span class="item">${item.description}</span>
<input type="hidden" name="id" value="${item.ID}"/>
<input type="submit" name="SelectButton" value="Select" />
</c:forEach>
</div>
</form:form>
However开发者_如何转开发, this gives me a "Data binding errors: 1" message in the log and the form isn't submitted to the controller.
I tried changing the myCommand.id from an int to a String, but then the value when it's submitted is id1,id2, id3... (all of the IDs in a comma delimited list) with no way of determining which button was pressed. I don't want to have to specify different actions for each button as the number of items can grow, and the action for them is all the same, just with a different ID.
How can I have multiple buttons in this form and get the value in the controller?
Why not just use a separate form for each item?
<c:forEach items="${model.availableitems}" var="item">
<form:form method="post" commandName="myCommand">
<span class="item">${item.description}</span>
<input type="hidden" name="id" value="${item.ID}"/>
<input type="submit" name="SelectButton" value="Select" />
</form:form>
</c:forEach>
You have 3 options -
1. Use multiple forms and have a submit button in each form as suggested above. The generated code wouldn't be very pretty to look at and it's usually considered bad practice to have multiple forms in a page.
2. Use a Javascript hack to set a hidden variable when you press the submit button.
3. If you have to handle fallback (without JavaScript), then there's a roundabout way to find out which button was clicked. Here's an example -
<form:form method="post" commandName="myCommand">
<c:forEach items="${model.availableitems}" var="item">
<span class="item">${item.description}</span>
<input type="submit" name="${item.ID}" value="Select" />
</c:forEach>
</form:form>
This set a unique id to each button. Since the request params go as key value pairs, we'll have to do a reverse lookup in this case as we have the value in the key position. Here's the java side of it.. not sure if this is the most efficient way to do it but it works.
String searchButtonName(final HttpRequest request) {
String buttonName = "";
Map<String, String[]> paramMap = request.getParameterMap();
if (MapUtils.isNotEmpty(paramMap)) {
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
/* Search for the button name as given in
the 'value' attribute for the input tag */
if ("Select".equals(entry.getValue()[0])) {
buttonName = entry.getKey();
break;
}
}
}
return buttonName;
}
instead of using submit button use a button which calls function which sets the value of hidden field and calls form.submit()
you can generate buttons using loop
You can use annotation parameter @RequestParam("SelectButton") String submit
in argument list of your controller.
精彩评论