package org.devgateway.toolkit.forms.wicket.components;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
import org.devgateway.toolkit.forms.wicket.components.form.BootstrapAddButton;
import org.devgateway.toolkit.forms.wicket.components.form.BootstrapDeleteButton;
import org.devgateway.toolkit.persistence.dao.AbstractAuditableEntity;
import java.util.List;
/**
* @author idobre
* @since 10/5/16
*
* Class that displays a list of <T> type with the possibility of adding/removing elements.
*
* @param <T> The current list data type
* @param <PARENT> The parent field data type
*/
public abstract class ListViewSectionPanel<T extends AbstractAuditableEntity, PARENT extends AbstractAuditableEntity>
extends CompoundSectionPanel<List<T>> {
private WebMarkupContainer listWrapper;
protected ListView<T> listView;
public ListViewSectionPanel(final String id) {
super(id);
}
/**
* Removes a child based on its index
*
* @param index
* @return
*/
private BootstrapDeleteButton getRemoveChildButton(final int index) {
BootstrapDeleteButton removeButton = new BootstrapDeleteButton("remove") {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
ListViewSectionPanel.this.getModelObject().remove(index);
listView.removeAll();
target.add(listWrapper);
}
};
removeButton.setOutputMarkupPlaceholderTag(true);
return removeButton;
}
/**
* Returns the new child button
*
* @return
*/
protected BootstrapAddButton getAddNewChildButton() {
BootstrapAddButton newButton = new BootstrapAddButton("newButton", new ResourceModel("newButton")) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
@SuppressWarnings("unchecked")
T newChild = createNewChild((IModel<PARENT>) ListViewSectionPanel.this.getParent().getDefaultModel());
ListViewSectionPanel.this.getModel().getObject().add(newChild);
listView.removeAll();
target.add(listWrapper);
}
};
newButton.setOutputMarkupPlaceholderTag(true);
return newButton;
}
@Override
protected void onInitialize() {
super.onInitialize();
setOutputMarkupId(true);
setOutputMarkupPlaceholderTag(true);
listWrapper = new TransparentWebMarkupContainer("listWrapper");
listWrapper.setOutputMarkupId(true);
add(listWrapper);
listWrapper.add(new Label("panelTitle", title));
listView = new ListView<T>("list", getModel()) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem<T> item) {
// we wrap the item model on a compound model so we can use the field ids as property models
final CompoundPropertyModel<T> compoundPropertyModel = new CompoundPropertyModel<>(item.getModel());
// we set back the model as the compound model, thus ensures the rest of the items added will benefit
item.setModel(compoundPropertyModel);
// we add the rest of the items in the listItem
populateCompoundListItem(item);
// we add the remove button
final BootstrapDeleteButton removeButton = getRemoveChildButton(item.getIndex());
item.add(removeButton);
}
};
listView.setReuseItems(true);
listView.setOutputMarkupId(true);
listWrapper.add(listView);
final BootstrapAddButton addButton = getAddNewChildButton();
add(addButton);
}
/**
* Use the constructor for new children and return the entity after setting
* its parent
*
* @param parentModel the model of the parent
* @return
*/
public abstract T createNewChild(IModel<PARENT> parentModel);
/**
* Populates the list item elements
*
* @param item
*/
public abstract void populateCompoundListItem(ListItem<T> item);
}