私はなんとかこの「ハック」を機能させることができました。それは、ジェリーが勧めた通りなので、クレジットはすべて彼に行きます。
簡単に言うと、コンセプトは、従来の構成を使用してビューを事前に入力すること<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>
ご覧のとおり、ビューには最も毛深い部分があります。(残念ながら)私のものと同じ状況に遭遇した人にとっては、それでも役立つことを願っています。乾杯!