考虑以下情况:
我的表单模型
public class PersonForm {
@NotNull
private String name;
/*usual getters and setters*/
}
我的控制器:
@Controller
@SessionAttribute(types={ PersonForm.class })
public class MyController {
@RequestAttribute(...)
public String render(final ModelMap map) {
/* get list of info and for each info
* create a PersonForm and put it in the modelmap
* under key p0, p1, p2, ..., pn
*/
}
public String submit(final ModelMap map,
@Valid final PersonForm form,
final BindingResult result) {
if (result.hasErrors()) {
// return to page
} else {
// do necessary logic and proceed to next page
}
}
}
最后是我的JSP视图
...
<c:forEach ...>
<form:form commandName="p${counter}">
... other form:elements and submit button goes here
</form:form>
</c:forEach>
...
正如您所看到的,我正在尝试处理同一类类型的多种形式。提交工作 - 它让我接受提交(...)方法就好了,验证也是如此。但重新呈现页面并没有显示预期的错误消息!
更糟糕的是 - 我检查了提交标题中传递的内容,并且没有任何表明提交的表单,因此无法区分另一个表单。这使我相信不可能有多种形式的同一类型......
除了Ajax之外,还有其他方法吗?
非常感谢。
答案 0 :(得分:2)
我设法让这个'黑客'上班。正如 jelies 所建议的那样,所有这些都归于他。
简单来说,概念是使用传统的<c:forEach>
构造预先填充您的视图。棘手的部分是每当按下相应行的“提交”按钮时,必须将所有信息注入隐藏表格并强制提交给控制器。如果屏幕再次呈现并出现一些错误,则脚本必须负责将值注入相应的行,包括错误。
1)我的模特
public class PersonForm {
private String id;
@NotNull
private String name;
/*usual getters and setters*/
}
2)我的控制器
@Controller
@SessionAttribute(/* the hidden form name, the person list */)
public class MyController {
@RequestAttribute(...)
public String render(final ModelMap map) {
/* get list of info and for each info
* create a PersonForm and put it in the modelmap
* under key p0, p1, p2, ..., pn
*/
}
public String submit(final ModelMap map,
@Valid final PersonForm form,
final BindingResult result) {
if (result.hasErrors()) {
// return to page
} else {
// do necessary logic and proceed to next page
}
}
}
3)我的观点
...
<form:form commandName="personForm" cssStyle="display: none;">
<form:hidden path="id"/>
<form:hidden path="name" />
<form:errors path="name" cssStyle="display: none;" />
</form:form>
...
<c:forEach var="p" items="${pList}">
<input type="text" id="${ p.id }Name" value="${ p.name }" />
<!-- to be filled in IF the hidden form returns an error for 'name' -->
<span id="${ p.id }nameErrorSpan"></span>
<button type="button" value="Submit" onclick="injectValuesAndForceSubmit('${ p.id }');" />
</c:forEach>
...
<script type="text/javascript">
injectValuesAndForceSubmit = function(id) {
$('#id').val( id ); // fill in the hidden form's id
$('#name').val( $('#'+id+'name').val() ); //fill in the hidden form's name
$('#personForm').submit(); //submit!
}
$(document).ready(function() {
var id = $('#id').val();
if (id.trim().length == 0) {
//Empty. Nothing to do here as this is a simple render.
} else {
//The page seems to be returning from some sort of error ... pre-fill the respective row!
$('#'+id+'name').val($('#name').val());
var hiddenNameErrorSpan = $('#name.errors');
if (hiddenNameErrorSpan) {
$('#'+id+'nameErrorSpan').text(hiddenNameErrorSpan.html());
}
} //else
}
</script>
正如你所看到的那样,视图中有最毛茸茸的部分 - 希望它仍然可以证明对于那些(不幸)遇到与我相同情况的人来说是有用的。干杯!
答案 1 :(得分:0)
所以,我建议最简单的方法是使用一个独特的隐藏外部表单和人物属性。当按下其中一个按钮时,相应地填写表格的人物属性并提交。有了这个,你就可以实现典型的弹簧形式提交/验证。
也许这个解决方案需要使用JavaScript,但我不知道如何处理具有多种形式的spring-mvc,我总是试图避免它,因为之前的尝试不成功。