很抱歉,如果在其他地方有人问过这个问题,但我环顾四周,找到了一些答案,但不是一个完整的例子,我仍然对此表示怀疑。
因此,我将一个自动填充列表从我的 Spring 控制器添加到我的 JSP,并且我想在我的 JavaScript / jQuery 函数内的列表中添加项目。可以吗?
我尝试了下面的代码来测试功能,但它不起作用(列表元素在生成的 html 中根本没有显示)。所以我不确定我是否搞乱了 JavaScript/Spring/JSP 语法,或者它是否根本不可能。
控制器代码:
@RequestMapping(value="/create_custobject.html",method = RequestMethod.GET)
public ModelAndView showCreateCustObjectPage() {
Map<String, Object> model = new HashMap<String, Object>();
CreateObjectForm form = new CreateObjectForm();
model.put("createObjectform", form);
return new ModelAndView("create_custobject", model) ;
}
表格代码:
public class CreateObjectForm {
private AutoPopulatingList<Criteria> ruleArray = new AutoPopulatingList<Criteria>(Criteria.class);
public AutoPopulatingList<Criteria> getRuleArray() {
return ruleArray;
}
public void setRuleArray(AutoPopulatingList<Criteria> ruleArray) {
this.ruleArray = ruleArray;
}
public CreateObjectForm() {}
}
标准代码:
public class Criteria{
String attribute;
String operator;
//... constructor + getters and setters
}
JavaScript / jQuery 代码(与 JSP 位于同一页面):
<script type="text/javascript">
$(document).ready(function(){
//startup functionality
var i = 0;
document.getElementById("addCriteria").onclick = function() {
$("#msgid").html("${ruleArray[i].attribute}");
${ruleArray[i].attribute} = $('#attributeValue').val();
${ruleArray[i].operator} = $('#operatorValue').val();
i++;
}
}
对于表单中的现有项目,请使用 jstl 作为
<c:forEach items="${form.items}" var="item" varStatus="status" >
<span class="count" >
<form:input path="items[${status.index}].field" />
这将呈现这样的形式
<form id = "idform" >
<span class="count" >
<input name="items[0].field" id="items0.field" />
</span>
</form>
然后你只需使用 javascript 添加新的表单“lines”和相应的索引
例如
var is = $('.count').size()
$('#idform span:last').after('<span class="count" ><input name="items[' + is + '].field"' + is + '.field" /></span>')
我认为如果你使用的是 spring 3 + 你不需要使用 AutopopulatedList ,任何集合就足够了。
您混合 JSP EL 和 Javascript 的方式不正确。您不能在 JSP 表达式中使用
var i
,即。 ${ruleArray[i].operator}
。我建议使用 JSTL 迭代列表并在脚本中创建属性。
此时,您的脚本可以设置为仅在表达式中使用字符串文字
0
。我假设您需要比这更强大的功能,您能更好地描述它吗?
$(document).ready(function(){
document.getElementById("addCriteria").onclick = function() {
$("#msgid").html("${ruleArray[0].attribute}");
//I assume you wanted to set the element to the value pulled from JSP EL
$('#attributeValue').val(${ruleArray[0].attribute});
$('#operatorValue').val(${ruleArray[0].operator});
}
}
使用 JSTL,解决方案将类似于:
<script>
var criteria = [];
<c:forEach var="criteria" items=${ruleArray}>
criteria.push({attr:${criteria.attribute}, oper: ${criteria.operator});
</c:forEach>
for(var i = 0; i < criteria.length; i++){
alert(criteria[i].attribute);
}
</script>
这个解决方案基本上使用JSTL来编写Javascript。修改控制器以返回 JSON 并在页面加载时进行 Ajax 调用可能是更好的解决方案。
在下面的行中,您在 jsp 代码中引用
i
,但 i 未定义:
$("#msgid").html("${ruleArray[i].attribute}");
定义
i
的javascript代码在客户端(即浏览器)上执行。 jsp 代码在服务器上执行,然后将渲染的 html 发送到客户端。
尽管该线程较旧且答案正确,但为了其他初学者的利益,并解释实现删除添加行的逻辑。
让我用最少的代码和带有 firstName、email、userName 和 sex 字段的用户示例来解释。
考虑到您从控制器发送 usersList 中的 3 个空用户,这将创建 3 个空行。现在您想要添加行并将添加的行动态绑定到 modelAttribute。
(如果是最初 3 行)如果您检查/查看页面源代码,您将看到
<input> tags
)具有不同的id,例如list0.firstName
list1.firstName
<input> tags
)具有不同的名称,例如list[0].firstName
list[1].firstName
每当提交表单时,服务器不会考虑id's(添加仅用于帮助客户端验证),但name属性将被解释为请求参数并用于构造您的modelAttribute,因此属性名称在插入时非常重要行。
那么,如何构造/追加新行?
如果我从 UI 提交 6 个用户,控制器应该从 usersList 接收 6 个用户对象。下面给出了实现相同目标的步骤
1. 右键
->
查看页面源。您将看到这样的行(您可以在第一行看到 *[0].*
,在第二行看到 *[1].*
)
<tr>
<td><input id="list0.firstName" name="list[0].firstName" type="text" value=""/></td>
<td><input id="list0.email" name="list[0].email" type="text" value=""/></td>
<td><input id="list0.userName" name="list[0].userName" type="text" value=""/></td>
<td>
<span>
<input id="list0.gender1" name="list[0].gender" type="radio" value="MALE" checked="checked"/>Male
</span>
<span>
<input id="list0.gender2" name="list[0].gender" type="radio" value="FEMALE"/>Female
</span>
</td>
</tr>
<tr>
<td><input id="list1.firstName" name="list[1].firstName" type="text" value=""/></td>
<td><input id="list1.email" name="list[1].email" type="text" value=""/></td>
<td><input id="list1.userName" name="list[1].userName" type="text" value=""/></td>
<td>
<span>
<input id="list1.gender1" name="list[1].gender" type="radio" value="MALE" checked="checked"/>Male
</span>
<span>
<input id="list1.gender2" name="list[1].gender" type="radio" value="FEMALE"/>Female
</span>
</td>
</tr>
'<tr>'+
'<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
'<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
...
'</tr>';
<tbody>
。提交表单时,行也会添加到 UI 中,新添加的行将在控制器中收到。删除行有点复杂,我会尝试用最简单的方式解释
// In Controller
@RequestMapping(value = "/app/admin/add-users", method = RequestMethod.GET)
public String addUsers(Model model, HttpServletRequest request)
{
List<DbUserDetails> usersList = new ArrayList<>();
ListWrapper userListWrapper = new ListWrapper();
userListWrapper.setList(usersList);
DbUserDetails user;
for(int i=0; i<3;i++)
{
user = new DbUserDetails();
user.setGender("MALE"); //Initialization of Radio button/ Checkboxes/ Dropdowns
usersList.add(user);
}
model.addAttribute("userListWrapper", userListWrapper);
model.addAttribute("roleList", roleList);
return "add-users";
}
@RequestMapping(value = "/app/admin/add-users", method = RequestMethod.POST)
public String saveUsers(@ModelAttribute("userListWrapper") ListWrapper userListWrapper, Model model, HttpServletRequest request)
{
List<DbUserDetails> usersList = userListWrapper.getList();
Iterator<DbUserDetails> itr = usersList.iterator();
while(itr.hasNext())
{
if(itr.next().getFirstName() == null)
{
itr.remove();
}
}
userListWrapper.getList().forEach(user -> {
System.out.println(user.getFirstName());
});
return "add-users";
}
//POJO
@Entity
@Table(name = "userdetails")
@XmlRootElement(name = "user")
public class DbUserDetails implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String firstName;
private String userName;
private String email;
private String gender;
//setters and getters
}
//list wrapper
public class ListWrapper
{
private List<DbUserDetails> list;
//setters and getters
}
在JSP中
<form:form method="post" action="${pageContext.request.contextPath}/app/admin/add-users" modelAttribute="userListWrapper">
<table class="table table-bordered">
<thead>
<tr>
<th><spring:message code="app.userform.firstname.label"/></th>
<th><spring:message code="app.userform.email.label"/></th>
<th><spring:message code="app.userform.username.label"/></th>
<th><spring:message code="app.userform.gender.label"/></th>
</tr>
</thead>
<tbody id="tbodyContainer">
<c:forEach items="${userListWrapper.list}" var="user" varStatus="loop">
<tr>
<td><form:input path="list[${loop.index}].firstName" /></td>
<td><form:input path="list[${loop.index}].email" /></td>
<td><form:input path="list[${loop.index}].userName" /></td>
<td>
<span>
<form:radiobutton path="list[${loop.index}].gender" value="MALE" /><spring:message code="app.userform.gender.male.label"/>
</span>
<span>
<form:radiobutton path="list[${loop.index}].gender" value="FEMALE" /><spring:message code="app.userform.gender.female.label"/>
</span>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="offset-11 col-md-1">
<button type="submit" class="btn btn-primary">SAVE ALL</button>
</div>
</form:form>
JSP中需要包含Javascript
var currentIndex = 3; //equals to initialRow (Rows shown on page load)
function addRow()
{
var rowConstructed = constructRow(currentIndex++);
$("#tbodyContainer").append(rowConstructed);
}
function constructRow(index)
{
return '<tr>'+
'<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
'<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
'<td><input id="list'+ index +'.userName" name="list['+ index +'].userName" type="text" value=""/></td>'+
'<td>'+
'<span>'+
'<input id="list'+ index +'.gender1" name="list['+ index +'].gender" type="radio" value="MALE" checked="checked"/>Male'+
'</span>'+
'<span>'+
'<input id="list'+ index +'.gender'+ index +'" name="list['+ index +'].gender" type="radio" value="FEMALE"/>Female'+
'</span>'+
'</td>'+
'</tr>';
}