Wicket and List Choice Transfers
Posted by Mischa Dasberg in the late evening: March 25, 2008
Consider the following scenario: we want to have two select boxes and we want to add options from one to the other and back.
Currently, this is not easily possible in Wicket, even though there are a lot of extensions available.
This blog describes an easy way to create a component which does just that!


For creating a Select box there are multiple options available. You can use a ListChoice for selecting a single option or a ListMultipleChoice for selecting multiple options.
So how do we start?
Well, first we need to create two ListMultipleChoice object. Lets give them the following names: originals and destinations
As you can see below, this isn't very hard.
// The Selected options in the list choices. private List<String> selectedOriginals; private List<String> selectedDestinations; ListMultipleChoice originals = new ListMultipleChoice("originals", new PropertyModel(this, "selectedOriginals"), new LoadableDetachableModel() { @Override protected Object load() { return Arrays.asList(new String[] {"one", "two", "three", "four", "five", "six"}); } }); ListMultipleChoice destinations = new ListMultipleChoice("destinations", new PropertyModel(this, "selectedDestinations"), new LoadableDetachableModel() { @Override protected Object load() { return new ArrayList<String>(); } });
and the matching HTML part:
<select wicket:id="originals" size="7" style="width:200px;"></select> <select wicket:id="destinations" size="7" style="width:200px;"></select>
Next we need two buttons, one for adding and one for removing options from a select box.
AjaxButton add = new AjaxButton("add") { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { update(target,selectedOriginals, originals, destinations); } }; AjaxButton remove = new AjaxButton("remove") { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { update(target, selectedDestinations, destinations, originals); } }; /** * Updates the select boxes. * @param target The {@link AjaxRequestTarget}. */ private void update(AjaxRequestTarget target, List<String> selections, ListMultipleChoice from, ListMultipleChoice to) { for (String destination : selections) { List<String> choices = getChoices(from); if (!to.getChoices().contains(destination)) { to.getChoices().add(destination); choices.remove(destination); from.setChoices(choices); } } target.addComponent(to); target.addComponent(from); }
and the matching HTML part:
<input wicket:id="add" type="button" value="→" /> <input wicket:id="remove" type="button" value="←" />
As you can see I use an AjaxButton, which is basically what you want for this example. We do not want to do a full page reload.
That's it.
Next thing we want to do is create a component that does all of this, so we can reuse it. After analysing, I found out that we only need a method which retrieves all options. I have called it getOriginalChoices();
If you look into the attached example project, you can see that it is now very easy to use it.
To use the Component you need to do the following:
ListMultipleChoiceTransfer listMultipleChoiceTransfer = new ListMultipleChoiceTransfer("test"){
@Override
public List getOriginalChoices() {
return Arrays.asList(new String[] {"one", "two", "three", "four", "five", "six"});
}
};
and the matching html
<span wicket:id="test">ListMultipleChoiceTransfer will be placed here</span>
I have attached the example project here so you can look into the code yourself.
Filed under:
March 26th, 2008 at 11:23 am
Hi Mischa,
You wrote: >Currently, this is not easily possible in Wicket, even though there are a lot of extensions available
I dont know Wicket, but i am wondering why you need AJAX-Wicket to do this. Why not write a simple javascript to do this. ?
Regards
Balaji
March 27th, 2008 at 12:22 am
I guess it’s a matter of what you regard as simple. The beauty of Wicket is in my opinion I don’t have to write Javascript at all. Isn’t that great :-).
April 22nd, 2008 at 6:53 pm
This has been around in wicket since the 1.2 release. It is called a Palette and lives in wicket-extensions core project.
http://wicketstuff.org/wicket13/compref/?wicket:bookmarkablePage=%3Aorg.apache.wicket.examples.compref.PalettePage