/*
* Copyright (c) 2016 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.wicket.extensions.ajax.markup.html;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.PropertyModel;
/**
* A dropdown that handles a list of selected objects. Rendering show objects
* currently selected. Ajax event is called whenever the list of selected objects
* changes.
*
* @author ymarcon
*/
public abstract class AjaxDropDownMultipleChoice extends DropDownChoice {
private List selected = new ArrayList();
private List selectable;
private Object selection;
private boolean keepSelection = false;
private final IChoiceRenderer userRenderer;
/**
* Constructor with the selectable objects and an object renderer.
*
* @param id
* @param selectable
* @param renderer
*/
@SuppressWarnings("serial")
public AjaxDropDownMultipleChoice(String id, List selectable, List currentSelection, IChoiceRenderer renderer) {
super(id, selectable);
setSelectable(selectable);
setSelected(currentSelection);
setNullValid(true);
setModel(new PropertyModel(this, "selection"));
userRenderer = renderer;
setChoiceRenderer(new IChoiceRenderer() {
@Override
public Object getDisplayValue(Object obj) {
Object rval;
if(userRenderer != null) rval = userRenderer.getDisplayValue(obj);
else if(obj != null) rval = obj.toString();
else rval = "";
if(selected.contains(obj)) return "- " + rval;
else return "+ " + rval;
}
@Override
public String getIdValue(Object obj, int idx) {
if(userRenderer != null) return userRenderer.getIdValue(obj, idx);
else if(obj != null) return obj.toString();
else return "";
}
});
add(new AjaxFormComponentUpdatingBehavior("onchange") {
@SuppressWarnings("unchecked")
@Override
protected void onUpdate(AjaxRequestTarget target) {
if(selection == null) return;
// keep or remove selection
if(selected.contains(selection)) selected.remove(selection);
else selected.add(selection);
// order the selected same as the selectable
List orderedSelected = new ArrayList();
for(Object obj : getSelectable()) {
if(selected.contains(obj)) orderedSelected.add(obj);
}
selected = orderedSelected;
onSelectionUpdate(selected, selection, target);
if(!keepSelection) {
selection = null;
target.addComponent(AjaxDropDownMultipleChoice.this);
}
}
});
}
public AjaxDropDownMultipleChoice(String id, List selectable, List selected) {
this(id, selectable, selected, null);
}
public AjaxDropDownMultipleChoice(String id, List selectable) {
this(id, selectable, null, null);
}
/**
* Method called on object selection ajax event.
*
* @param language
* @param target
*/
protected abstract void onSelectionUpdate(List selected, Object selection, AjaxRequestTarget target);
/**
* Keep selection non null after selection event.
*
* @return
*/
protected boolean isKeepSelection() {
return keepSelection;
}
/**
* Set keep selection non null after selection event.
*
* @param keepSelection
*/
protected void setKeepSelection(boolean keepSelection) {
this.keepSelection = keepSelection;
}
/**
* Get the selectable objects.
*
* @return
*/
public List getSelectable() {
return selectable;
}
/**
* Set the selectable objects.
*
* @param selectable
*/
public void setSelectable(List selectable) {
this.selectable = selectable;
}
/**
* Get the selected objects.
*
* @return
*/
public List getSelected() {
return selected;
}
/**
* Set the selected objects.
*
* @param selected
*/
public void setSelected(List selected) {
this.selected = selected;
}
/**
* Set the objects selectable selected up to the given last index included.
*
* @param lastIndex
*/
@SuppressWarnings("unchecked")
public void setSelected(int lastIndex) {
if(selected == null || selectable == null) return;
selected.clear();
for(int i = 0; i <= lastIndex; i++) {
if(i < selectable.size()) selected.add(selectable.get(i));
else return;
}
}
/**
* Get the last selection.
*
* @return
*/
public Object getSelection() {
return selection;
}
/**
* Set the last selection.
*
* @param selection
*/
public void setSelection(Object selection) {
this.selection = selection;
}
}