Wicket and List Choice Transfers

Mischa Dasberg

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!

  select transfer   select transfer


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 selectedOriginals;
  private List 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();
      }
    });

and the matching HTML part:



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 selections, ListMultipleChoice from, ListMultipleChoice to) {
    for (String destination : selections) {
      List 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:


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

ListMultipleChoiceTransfer will be placed here

I have attached the example project here so you can look into the code yourself.

Comments (5)

  1. Balaji D Loganathan - Reply

    March 26, 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

  2. Lars Vonk - Reply

    March 27, 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 :-).

  3. Igor Vaynberg - Reply

    April 22, 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

  4. Sesh R. - Reply

    May 4, 2010 at 2:45 pm

    This is a cool article. The great thing about wicket is that there is no need to write any javascript which is a pain. The flip side is the documentation available for Wicket is not great.

  5. Mauro - Reply

    October 8, 2010 at 6:43 pm

    Hi, im ussing you example but could you tell me how can i make that te selected options initialize with some options selected???

    thanks

Add a Comment