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

Reply via email to