4.9. Selecting Items

IT Mill Toolkit provides several alternative choices for selecting one or more items from a list. The selection components allow selecting one or more items from a list of items. The items are Item objects contained in a Container. The choices are based on the AbstractSelect base class.

The following selection classes are available:

Table 4.2. Selection Components

Select Provides a drop-down list for single selection and a multi-line list in multiselect mode.
NativeSelect Provides selection using the native selection component in the browser, typically a drop-down list for single selection and a multi-line list in multiselect mode. This uses the <select> element in HTML.
OptionGroup Shows the items as a vertically arranged group of radio buttons in the single selection mode and of check boxes in multiple selection mode.
TwinColSelect Shows two list boxes side by side where the user can select items from a list of available items and move them to a list of selected items using control buttons.

In addition, the Tree and Table components allow special forms of selection. They also inherit the AbstractSelect.

The selection components provide the current selection as an item identifier from the Property interface of the component, that is, as the value of the component. You can get the value, which is an item identifier object, with getValue() of the Property interface. In multiselect mode, the property will be an unmodifiable set of item identifiers. If no item is selected, the property will be null in single selection mode or an empty collection in multiselect mode.

New items are added with the addItem() method, implemented for the Container interface. The method takes the item identifier (IID) object as a parameter, and by default uses the identifier also as the caption of the item. The identifier is typically a String. The addItem() method also creates an empty Item, which itself has little relevance in the Select component, as the properties of an item are not used in any way by the component.

/* Create a Select component and add it to a layout. */
Select select = new Select ("Select something here");
main.addComponent(select);
	
/* Fill the component with some items. */
final String[] planets = new String[] {"Mercury", "Venus", "Earth", "Mars",
                                       "Jupiter", "Saturn", "Uranus", "Neptune"};
for (int i=0; i<planets.length; i++)
    select.addItem(planets[i]);

We could as well have added the item identifiers as integers, for example, and set the captions explicitly.

The Select and NativeSelect components will show "-" selection when no actual item is selected. This is the null selection item identifier. You can set an alternative ID with setNullSelectionItemId(). Setting the alternative null ID is merely a visual text; the getValue() will still return null value if no item is selected, or an empty set in multiselect mode.

The item identifier of the currently selected item will be set as the property of the Select object. You can access it with the getValue method of the Property interface of the component. Also, when handling changes in a Select component with the Property.ValueChangeListener interface, the Property.ValueChangeEvent will have the selected item as the property of the event, accessible with the getProperty method.

Figure 4.12. Retrieval of the Currently Selected Item

Retrieval of the Currently Selected Item

The item and its identifier can be of any object type. The caption of the items can be retrieved from various sources, as defined with the caption mode of the component, which you can set with the setItemCaptionMode() method. The default mode is ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID. In addition to a caption, an item can have an icon. The icon of an item is set with setItemIcon().

Table 4.3. Caption Modes for Selection Components

ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID This is the default caption mode and its flexibility allows using it in most cases. By default, the item identifier will be used as the caption. The caption is retrieved with toString() method of the item identifier object. If the caption is specified explicitly with setItemCaption(), it overrides the item identifier.
ITEM_CAPTION_MODE_EXPLICIT Captions must be explicitly specified with setItemCaption(). If they are not, the caption will be empty. Such items with empty captions will nevertheless be displayed in the Select component as empty rows. If they have an icon, they will be visible.
ITEM_CAPTION_MODE_ICON_ONLY Only icons are shown, captions are hidden. Notice that icons are not supported in the themes in IT Mill Toolkit version 4 (see below).
ITEM_CAPTION_MODE_ID

String representation of the item identifier object is used as caption. This is useful when the identifier is actually an application specific object. For example:

class Planet extends Object {
        String planetName;
        Planet (String name) {
            planetName = name;
        }
        public String toString () {
            return "The Planet " + planetName;
        }
    }
    ...
    SelectExample (Application application) {
        ...
        for (int i=0; i<planets.length; i++)
            select.addItem(new Planet(planets[i]));
        ...
    }
ITEM_CAPTION_MODE_INDEX Index number of item is used as caption. This caption mode is applicable only to data sources that implement the Container.Indexed interface. If the interface is not available, the component will throw a ClassCastException. The Select component itself does not implement this interface, so the mode is not usable without a separate data source. An IndexedContainer, for example, would work.
ITEM_CAPTION_MODE_ITEM String representation of item, acquired with toString(), is used as the caption. This is applicable mainly when using a custom Item class, which also requires using a custom Container that is used as a data source for the Select component.
ITEM_CAPTION_MODE_PROPERTY Item captions are read from the String representation of the property with the identifier specified with setItemCaptionPropertyId(). This is useful, for example, when you have a Table component that you use as the data source for the Select, and you want to use a specific table column for captions.

Notice that while the Select component allows associating an icon with each item with setItemIcon(), the icons are not supported in the themes in IT Mill Toolkit version 4. This is because HTML does not support images inside select elements. Icons are also not really visually applicable for optiongroup and twincol styles.

4.9.1. Basic Select Component

The Select component allows, in single selection mode, selecting an item from a drop-down list, or in multiple selection mode, from a list box that shows multiple items.

Figure 4.13. The Select Component

The Select Component

Combo Box Behaviour

The Select component will act as a combo box in single selection mode, allowing either to choose the value from the drop-down list or to write the value in the text field part of the component.

Filtered Selection

The Select component allows filtering the items available for selection. The component shows as an input box for entering text. The text entered in the input box is used for filtering the available items shown in a drop-down list. Pressing Enter will complete the item in the input box. Pressing Up- and Down-arrows can be used for selecting an item from the drop-down list. The drop-down list is paged and clicking on the scroll buttons will change to the next or previous page. The list selection can also be done with the arrow keys on the keyboard. The shown items are loaded from the server as needed, so the number of items held in the component can be quite large.

IT Mill Toolkit provides two filtering modes: FILTERINGMODE_CONTAINS matches any item that contains the string given in the text field part of the component and FILTERINGMODE_STARTSWITH matches only items that begin with the given string. The filtering mode is set with setFilteringMode(). Setting the filtering mode to the default value FILTERINGMODE_OFF disables filtering.

Select select = new Select("Enter containing substring");

select.setFilteringMode(AbstractSelect.Filtering.FILTERINGMODE_CONTAINS);

/* Fill the component with some items. */
final String[] planets = new String[] {"Mercury", "Venus", "Earth",
        "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" };

for (int i = 0; i < planets.length; i++)
    for (int j = 0; j < planets.length; j++) {
        select.addItem(planets[j] + " to " + planets[i]);

The above example uses the containment filter that matches to all items containing the input string. As shown in Figure 4.14, “Filtered Selection” below, when we type some text in the input area, the drop-down list will show all the matching items.

Figure 4.14. Filtered Selection

Filtered Selection

The FilterSelect demo in the IT Mill Toolkit Demo Application provides an example of filtering items in a Select component.

CSS Style Rules

.i-filterselect { }
.i-filterselect-input { }
.i-filterselect-button { }
.i-filterselect-suggestpopup { }
.i-filterselect-prefpage-off { }
.i-filterselect-suggestmenu { }
.i-filterselect-status { }

In its default state, only the input field of the Select component is visible. The entire component is enclosed in i-filterselect style, the input field has i-filterselect-input style and the button in the right end that opens and closes the drop-down result list has i-filterselect-button style.

The drop-down result list has an overall i-filterselect-suggestpopup style. It contains the list of suggestions with i-filterselect-suggestmenu style and a status bar in the bottom with i-filterselect-status style. The list of suggestions is padded with an area with i-filterselect-prefpage-off style above and below the list.

4.9.2. Native Selection Component NativeSelect

NativeSelect offers the native selection component in web browsers, using an HTML <select> element. In single selection mode, the component is shown as a drop-down list, and in multiple selection mode as a list box.

CSS Style Rules

.i-select-optiongroup {}
.i-checkbox, .i-select-option {}
.i-radiobutton, .i-select-option {}

The i-select-optiongroup is the overall style for the component. Each check box will have the i-checkbox style and each radio button the i-radiobutton style. Both the radio buttons and check boxes will also have the i-select-option style that allows styling regardless of the option type.

4.9.3. Radio Button and Check Box Groups with OptionGroup

The OptionGroup class provides selection from alternatives using a group of radio buttons in single selection mode. In multiple selection mode, the items show up as check boxes.

OptionGroup optiongroup = new OptionGroup("My Option Group");

/* Use multiple selection mode. */
myselect.setMultiSelect(true);

Figure 4.15. Radio Button Group

Radio Button Group

It is also possible to create the check boxes individually using the CheckBox class, as described in Section 4.8, “Check Box”. The advantages of the OptionGroup component are that as it maintains the individual check box objects, you can get the array of all currently selected items easily, and that you can easily change the appearance of the component to another style.

CSS Style Rules

.i-select-optiongroup {}
.i-checkbox, .i-select-option {}
.i-radiobutton, .i-select-option {}

The i-select-optiongroup is the overall style for the component. Each check box will have the i-checkbox style and each radio button the i-radiobutton style. Both the radio buttons and check boxes will also have the i-select-option style that allows styling regardless of the option type.

4.9.4. Twin Column Selection with TwinColSelect

The TwinColSelect class provides a multiple selection component that shows two lists side by side. The user can select items from the list on the left and click on the ">>" button to move them to the list on the right. Items can be moved back by selecting them and clicking on the "<<" button.

Figure 4.16. Twin Column Selection

Twin Column Selection

CSS Style Rules

.i-select-twincol {}
.i-select-twincol-options {}
.i-select-twincol-selections {}
.i-select-twincol-buttons {}
.i-select-twincol-deco {}

4.9.5. Allowing Adding New Items

The selection components allow the user to add new items, with a user interface similar to combo boxes in desktop user interfaces. If the newItemsAllowed mode is enabled with the setNewItemsAllowed() method, a text box for entering new items will be displayed beside the selection component. Clicking on the "+" button adds the item to the component.

Figure 4.17. Select Component with Adding New Items Allowed

Select Component with Adding New Items Allowed

The identifier of an item added by the user will be a String object identical to the caption of the item. You should take this into account if the item identifier of automatically filled items is some other type or otherwise not identical to the caption.

Adding new items is possible in both single and multiple selection modes and in all styles. Adding new items may not be possible if the Select is bound to an external Container that does not allow adding new items.

4.9.6. Multiple Selection Mode

Setting the Select, NativeSelect, or OptionGroup components to multiple selection mode with the setMultiSelect() method changes their appearance to allow selecting multiple items. By holding the Ctrl or Shift key pressed, the user can select multiple items.

See also the behaviour of the component in multiSelect mode with other styles below. With the twincol style, the selection is done by moving items from a list to a list of selected items. With the optiongroup style, the items are displayed as check boxes.

myselect.setMultiSelect(true);

In multiple selection mode, the property of a Select object will be an array of currently selected items.

/* Let us add an implementation of the ValueChangeListener interface. */
public class SelectExample extends CustomComponent implements Property.ValueChangeListener {
    /* Create a Select object with a caption. */
    Select select = new Select("This is a Select component");

    VerticalLayout layout = new VerticalLayout();
    Label status = new Label("-");
    
    SelectExample () {
        setCompositionRoot (layout);
        layout.addComponent(select);

        /* Fill the component with some items. */
        final String[] planets = new String[] {"Mercury", "Venus", "Earth", "Mars",
                                               "Jupiter", "Saturn", "Uranus", "Neptune"};
        for (int i=0; i<planets.length; i++)
            select.addItem(planets[i]);

        /* By default, the change event is not triggered immediately
         * when the selection changes. This enables it. */
        select.setImmediate(true);
        
        /* Listen for changes in the selection. */
        select.addListener(this);

        layout.addComponent(status);
    }

    /* Respond to change in the selection. */
    public void valueChange(Property.ValueChangeEvent event) {
        /* The event.getProperty() returns the Item ID (IID) of the
         * currently selected item in the component. */
        status.setValue("Currently selected item ID: " + event.getProperty());
    }
}