GitHub

User guideForms

Select several values

Let the user select several values from a list with ListMultipleChoice, or move them between two lists with Palette.

How-toWicket 10 and later

You need this when the user picks any number of values from a list that is too long for checkboxes. For a short list, checkboxes are easier to use.

Select several values from a list

A ListMultipleChoice renders a <select multiple>. The user holds Ctrl (or Command on a Mac) to select more than one option. Its model holds the collection of selected choices.

TeamPage.java

IModel<List<Person>> people = LoadableDetachableModel.of(personService::findAll);

ListMultipleChoice<Person> members = new ListMultipleChoice<>("members",
    LambdaModel.of(team, Team::getMembers, Team::setMembers),
    people,
    new LambdaChoiceRenderer<>(Person::getFullName, Person::getId));
members.setMaxRows(8);
form.add(members);

TeamPage.html

<select wicket:id="members"></select>

Wicket adds the multiple attribute, and a size attribute from setMaxRows() unless the markup has one. Give the renderer an id, so that the selection survives a change in the list.

A ListChoice looks the same but lets the user pick only one value. It works like a DropDownChoice that shows several rows.

Move values between two lists

A Palette from wicket-extensions shows the available choices on the left and the selected ones on the right, with buttons to move them across. Users find it easier than Ctrl-clicking, and the selection stays visible.

Palette<Person> palette = new Palette<>("members",
    LambdaModel.of(team, Team::getMembers, Team::setMembers),
    people,
    new LambdaChoiceRenderer<>(Person::getFullName, Person::getId),
    10,      // visible rows
    true);   // show buttons to change the order
palette.add(new DefaultTheme());
form.add(palette);
<div wicket:id="members"></div>

The choice renderer of a Palette must return a real id, not the position in the list. With ordering turned on, the user can move selected values up and down, and the model gets them in that order. A constructor with one more boolean adds buttons to move all choices at once.

DefaultTheme adds a stylesheet that places the two lists side by side. Without it, you style the CSS classes of the palette yourself: palette-choices, palette-buttons, palette-selected and palette-header.

Change the headers with the keys palette.available and palette.selected in your properties file:

palette.available=Everyone
palette.selected=In this team

Write the options yourself

When you need control over each <option>, for example to add <optgroup> elements to a multiple select, use Select with SelectOptions from wicket-extensions. For several values, the model object of the Select must be a collection; Wicket clears it and adds the selected values. Each option is a component, so this uses more memory than a ListMultipleChoice.

<select wicket:id="members" multiple>
    <optgroup label="Developers">
        <wicket:container wicket:id="developers">
            <option wicket:id="option">name</option>
        </wicket:container>
    </optgroup>
</select>
Select<List<Person>> select = new Select<>("members",
    LambdaModel.of(team, Team::getMembers, Team::setMembers));
form.add(select);
select.add(new SelectOptions<>("developers", developers,
    new IOptionRenderer<Person>() {
        @Override
        public String getDisplayValue(Person person) {
            return person.getFullName();
        }

        @Override
        public IModel<Person> getModel(Person person) {
            return Model.of(person);
        }
    }));