Несмотря на то, что этот поток старше и на него дан правильный ответ, в интересах других новичков, а также для объяснения логики для удаления добавленных строк.
Позвольте мне объяснить с помощью минимального кода и примера пользователя с полями firstName, email, userName и gender.
Учитывая, что вы отправляете 3 пустых пользователя в список пользователей из контроллера, это создаст 3 пустых строки. И теперь вы хотите добавить строки и динамически привязать добавленные строки к modelAttribute.
(в случае начальных 3 строк)Если вы проверите/просмотрите исходный код страницы, вы увидите
- Строки (
<input> tags
) с разными идентификаторами, например list0.firstName
list1.firstName
- Строки (
<input> tags
) с разными именами, например list[0].firstName
list[1].firstName
Всякий раз, когда форма отправляется, идентификаторы не учитываются сервером (добавляются только для проверки на стороне клиента), но атрибут имени будет интерпретироваться как параметр запроса и использоваться для создания атрибута модели. , поэтому имена атрибутов очень важны при вставке строк.
Добавление строки
Итак, как построить/добавить новые строки?
Если я отправлю 6 пользователей из пользовательского интерфейса, контроллер должен получить 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>
- Скопируйте первую строку и создайте строку javascript и замените «0» индексом имени переменной. Как указано в образце ниже
'<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>
. Строки добавляются в пользовательский интерфейс, а также при отправке формы новые добавленные строки будут получены в контроллере.
Удаление строки
Удаление строки немного сложно, я постараюсь объяснить проще
- Предположим, вы добавили row0, row1, row2, row3, row4, row5
- Удалил строку 2, строку 3. Не просто скрыть строку, а удалить ее из DOM, перехватив событие.
- Теперь строки row0, row1, row4, row5 будут отправлены, но в контроллере ваш список пользователей будет иметь 6 пользовательских объектов, но user[2].firstName будет нулевым, а user[3].firstName будет нулевым.
- Итак, в вашем контроллере выполните итерацию и проверьте значение null и удалите пользователя. (Используйте итератор, не используйте foreach для удаления объекта пользователя)
Код публикации для новичков.
// 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>
Javascript должен быть включен в JSP
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>';
}
person
PraveenKumar Lalasangi
schedule
05.09.2019