OK so this is what I have so far. Seems to work OK. public class DropDownPalette<T> extends FormComponentPanel {
private static final String UNSELECTED_ID = "unselected"; private static final String SELECT_ACTION_ID = "select"; private static final String SELECTED_ID = "selected"; private static final String SELECTED_NAME_ID = "selected_name"; private static final String UNSELECT_ID = "unselect"; private IModel choicesModel; private IChoiceRenderer choiceRenderer; private transient List<T> selectedChoices; private transient List<T> unselectedChoices; private String[] ids; public DropDownPalette(String id, IModel model, IModel choicesModel, IChoiceRenderer choiceRenderer) { super(id, model); setOutputMarkupId(true); this.choicesModel = choicesModel; this.choiceRenderer = choiceRenderer; IModel unselectedChoices = new LoadableDetachableModel() { @Override protected Object load() { return getUnselectedChoices(); } }; DropDownChoice choice = new DropDownChoice(UNSELECTED_ID, new Model(), unselectedChoices, choiceRenderer); choice.add(new OnChangeAjaxBehavior() { @Override protected void onUpdate(AjaxRequestTarget target) { target.addComponent(DropDownPalette.this); } }); add(choice); add(new AjaxLink(SELECT_ACTION_ID) { @Override public void onClick(AjaxRequestTarget target) { getModelCollection().add(getCurrentChoice()); setCurrentChoice(null); initIds(); onItemSelected(target); target.addComponent(DropDownPalette.this); } @SuppressWarnings("unchecked") private T getCurrentChoice() { return (T) getParent().get(UNSELECTED_ID).getModelObject(); } private void setCurrentChoice(T choice) { getParent().get(UNSELECTED_ID).setModelObject(choice); } @Override protected void onBeforeRender() { setVisibilityAllowed(getCurrentChoice() != null); super.onBeforeRender(); } @Override protected boolean callOnBeforeRenderIfNotVisible() { return true; } }); IModel selectedChoices = new AbstractReadOnlyModel() { @Override public Object getObject() { return getSelectedChoices(); } }; add(new ListView(SELECTED_ID, selectedChoices) { @Override protected void populateItem(ListItem item) { Object displayValue = getChoiceRenderer().getDisplayValue(item.getModelObject()); item.add(new Label(SELECTED_NAME_ID, new Model(String.valueOf(displayValue)))); item.add(new AjaxLink(UNSELECT_ID) { @Override @SuppressWarnings("SuspiciousMethodCalls") public void onClick(AjaxRequestTarget target) { getModelCollection().remove(getParent().getModelObject()); flushSelectedChoices(); // in order to reload the choices onItemUnselected(target); target.addComponent(DropDownPalette.this); } }); } }); } protected void onItemUnselected(AjaxRequestTarget target) {} protected void onItemSelected(AjaxRequestTarget target) {} @Override protected void convertInput() { setConvertedInput(getSelectedChoices()); } protected void onBeforeRender() { if (!getForm().hasError()) { initIds(); } super.onBeforeRender(); } @SuppressWarnings("unchecked") public List<T> getSelectedChoices() { if (selectedChoices == null) { IChoiceRenderer renderer = getChoiceRenderer(); if (ids.length == 0) { return Collections.EMPTY_LIST; } selectedChoices = new ArrayList<T>(ids.length); for (String id : ids) { for (T choice : getChoices()) { if (renderer.getIdValue(choice, 0).equals(id)) { selectedChoices.add(choice); break; } } } } return selectedChoices; } @SuppressWarnings("unchecked") public List<T> getUnselectedChoices() { if (unselectedChoices == null) { Collection<T> choices = getChoices(); if (choices.size() - ids.length == 0) { return Collections.EMPTY_LIST; } unselectedChoices = new ArrayList<T>(Math.max(1, choices.size() - ids.length)); for (T choice : choices) { final String choiceId = getChoiceRenderer().getIdValue(choice, 0); boolean selected = false; for (String id : ids) { if (id.equals(choiceId)) { selected = true; break; } } if (!selected) { unselectedChoices.add(choice); } } } return unselectedChoices; } private void flushSelectedChoices() { selectedChoices = null; } private void initIds() { IChoiceRenderer renderer = getChoiceRenderer(); Iterator selection = getModelCollection().iterator(); ids = new String[getModelCollection().size()]; int i = 0; while (selection.hasNext()) { ids[i] = renderer.getIdValue(selection.next(), i++); } } @SuppressWarnings("unchecked") public Collection<T> getChoices() { return (Collection<T>) choicesModel.getObject(); } @SuppressWarnings("unchecked") public Collection<T> getModelCollection() { return (Collection<T>) getModelObject(); } public IChoiceRenderer getChoiceRenderer() { return this.choiceRenderer; } @Override protected void onDetach() { selectedChoices = null; unselectedChoices = null; super.onDetach(); } } -- View this message in context: http://apache-wicket.1842946.n4.nabble.com/Hybrid-palette-with-DropDownChoice-and-ListView-tp4664445p4664450.html Sent from the Users forum mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org