Reputation: 2089
I have a way to add panels in a listview. Each panel is associated with an Object of type Type. I have an 'add' and an some 'remove' AjaxSubmitLinks. Both have setDefaultFormProcessing(false) because I want non-submitted / validated values to remain when someone add or removes an element. setReuseItems(true) is set for the ListView. Please see the code snippet below.
ListView itemContainer = new ListView<Type>("list", getList()) {
@Override
protected void populateItem(final ListItem<Type> listItem) {
final Component element = createComponent(listItem.getModel());
listItem.add(element);
listItem.add(new AjaxSubmitLink("remove") {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
getList().remove(listItem.getIndex());
target.add(wrapper);
}
}.setDefaultFormProcessing(false));
}
};
itemContainer.setReuseItems(true);
add(itemContainer);
add(new AjaxSubmitLink("add") {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
Type object = addObject();
getList().add(object);
target.add(wrapper);
}
@Override
public boolean isVisible() {
return getList().size() < DSAddableField.this.max && isEditable();
}
}.setDefaultFormProcessing(false));
Where wrapper contains everything, so everything is reloaded with Ajax. All works well, expcet no matter which remove link I click the last element is being removed. equals() method is overriden on Type based on a UUID check. I did a debug and it would seem to me that the right element is removed from the ListModel, but wrong values are sent down by the ajax response.
How can I get this to work? I tried to remove setReuseItem(true), but than the non-saved values for list items were not reloaded. (Panels contain lot of input fields)
Any suggestions?
UPDATE:
I already tried to remove the object with getList().remove(listItem.getModelObject()), this was second solution but still failed.
Regardless if I use remove by index or by modelobject the right element is being removed from the list when using debugger.
UDAPTE 2:
If I remove "final int index = listItem.getIndex();" the right element is removed opposed to the last one but when I add a new one to the list non saved inputs are cleared which is the original problem I'm trying to solve. Please advise.
Upvotes: 1
Views: 629
Reputation: 1894
This belongs to your 2nd Edit:
If you use target.add(wrapper);
you read the whole component and thus rerender it.
If you put your populateItem in a WebMarkupContainer
you can rerender only this item.
protected void populateItem(final ListItem<Type> listItem) {
WebMarkupContainer cont = new WebMarkupContainer("cont");
cont.setOutputMarkupId(true);
cont.setOutputMarkupPlaceholderTag(true);
final Component element = createComponent(listItem.getModel());
cont.add(element);
cont.add(new AjaxSubmitLink("remove") {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
getList().remove(listItem.getIndex());
target.add(cont);
}
}.setDefaultFormProcessing(false));
listItem.add(cont);
}
Upvotes: 2
Reputation: 1289
I think the problem is listItem.getIndex();
When you call that method to get the index, listItem will be the last element in the list.
Try:
@Override
protected void populateItem(final ListItem<Type> listItem) {
final Component element = createComponent(listItem.getModel());
listItem.add(element);
final int index = listItem.getIndex();
listItem.add(new AjaxSubmitLink("remove") {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
getList().remove(index);
target.add(wrapper);
}
}.setDefaultFormProcessing(false));
Upvotes: 0
Reputation: 1894
I checked the solution I provided before in a comment myself, this should do it:
getList().remove(listItem.getModelObject());
Although I'm not sure if this would not just give a new List. I would do something like this:
List<Type> myList = getList();
ListView itemContainer = new ListView<Type>("list", myList) {
myList.remove(listItem.getModelObject());
}
Upvotes: 0