summaryrefslogtreecommitdiffstats
path: root/documentation/components/components-selection.asciidoc
blob: 1b627447864813b34318a3dbb772505d3b85fe62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
---
title: Selection Components
order: 5
layout: page
---

[[components.selection]]
= Selection Components

Vaadin offers many alternative ways for selecting one or more items. The core
library includes the following selection components, all based on the
[classname]#AbstractSelect# class:

// TODO Only use section numbers here, prefixed with "Section", not include section title

[classname]#ComboBox# (<<components-combobox#components.combobox,"ComboBox">>)::
A drop-down list with a text box, where the user can type text to find matching items.
The component also provides an input prompt and the user can enter new items.

[classname]#ListSelect# (<<components-listselect#components.listselect,"ListSelect">>)::
A vertical list box for selecting items in either single or multiple selection mode.

[classname]#NativeSelect# (<<components-nativeselect#components.nativeselect, "NativeSelect">>)::
Provides selection using the native selection component of the browser, typically a drop-down list for single selection and a multi-line list in multiselect mode.
This uses the [literal]#++<select>++# element in HTML.

[classname]#OptionGroup# (<<components-optiongroup#components.optiongroup,"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.

[classname]#TwinColSelect# (<<components-twincolselect#components.twincolselect, "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 [classname]#Tree#, [classname]#Table#, and [classname]#TreeTable# components allow special forms of selection.
They also inherit [classname]#AbstractSelect#.

[[components.selection.databinding]]
== Binding Selection Components to Data

The selection components typically bound to list of items obtained from backend system.
You can give the the list of items in the constructor or set it set
[methodname]#setItems()#. Read more in
<<dummy/../../../framework/datamodel/datamodel-overview.asciidoc#datamodel.overview,"Binding
Components to Data">>.

You can get the current selection as the
value of the selection component using [methodname]#getSelected# defined in
[interfacename]#Select# interface. Also selection changes are handled as
selection change events, as is described later.

[[components.selection.adding]]
== Adding New Items

New items are added with the [methodname]#addItems()# method.

[source, java]
----
// Create a selection component
ComboBox<String> select = new ComboBox<>("Select a planet");

// Add items to select
select.setItems("Mercury","Venus","Earth");
----

[[components.selection.captions]]
== Item Captions

The items are typically a strings, in which case they can be used as the
caption, but can be any object type. We could as well have given Planet instances
for the items and use captions generated based on them
[methodname]#setItemCaptionProvider()# method.


[source, java]
----
// List of Planet objects
List<Planet> planets = new ArrayList<>();
planets.add(new Planet("Mercury"));
planets.add(new Planet("Venus"));
planets.add(new Planet("Earth"));

// Create a selection component
ComboBox<Planet> select = new ComboBox<>("My Select");

// Add an items to the ComboBox
select.setItems(planets);

select.setItemCaptionProvider(planet -> planet.getName());
// or even select.setItemCaptionProvider(Planet::getName);

// Select the first
select.select(planets.get(0));
----

In addition to a caption, an item can have an icon. The icon is set with
[methodname]#setItemIconProvider()#.

Typical use cases for captions are:

Using the items as the caption: the caption is
retrieved with [methodname]#toString()# method from the item. This is useful
for simple objects like String or Integers, but also for objects that have
human readable output for [methodname]#toString()# .

+
[source, java]
----
ComboBox<Planet> select = new ComboBox<>("Inner Planets");

// A class that implements toString()
class Planet implements Serializable {
    String planetName;

    Planet(String name) {
        planetName = name;
    }

    public String toString () {
        return "The Planet " + planetName;
    }
}

// Use such objects as items
List<Planet> planets = new ArrayList<>();
planets.add(new Planet("Mercury"));
planets.add(new Planet("Venus"));
planets.add(new Planet("Earth"));

select.addItems(planets);
----

Using a field of a item as caption: the caption is retrieved using the
[interfacename]#ItemCaptionProvider# typically given as Java 8 lambda:



INDEX::
Index number of item is used as caption.
This caption mode is applicable only to data sources that implement the [interfacename]#Container.Indexed# interface.
If the interface is not available, the component will throw a
[classname]#ClassCastException#.
The [classname]#AbstractSelect# itself does not implement this interface, so the mode is not usable without a separate data source.
An [classname]#IndexedContainer#, for example, would work.

ITEM:: [classname]#String# representation of item, acquired with
[methodname]#toString()#, is used as the caption. This is applicable mainly when
using a custom [classname]#Item# class, which also requires using a custom
[classname]#Container# that is used as a data source for the selection
component.

PROPERTY:: Item captions are read from the [classname]#String# representation of the
property with the identifier specified with
[methodname]#setItemCaptionPropertyId()#. This is useful, for example, when you
have a container that you use as the data source for the selection component,
and you want to use a specific property for caption.

+
In the example below, we bind a selection component to a bean container and use
a property of the bean as the caption.

+
[source, java]
----
// A class that implements toString()
class Planet implements Serializable {
    Integer id;
    String planetName;

    Planet(Integer id, String name) {
        this.id = id
        this.planetName = name;
    }

    public String toString () {
        return "The Planet " + planetName;
    }

    public Integer getId () {
        return id;
    }


    public String getName () {
        return planetName;
    }

}

// Put some example data
List<Planet> planets = new ArrayList<>();
planets.add(new Planet(1, "Mercury"));
planets.add(new Planet(2, "Venus"));
planets.add(new Planet(3, "Earth"));
planets.add(new Planet(4, "Mars"));

// Create a selection component
ComboBox<Planet> select = new ComboBox<>("Planets");

// Set the caption provider to read the
// caption directly from the 'name'
// property of the bean
select.setItemCaptionProvider(Planet::getName);
----

[[components.selection.getset]]
== Getting and Setting Selection

You can get the item with [methodname]#getSelected()# of the
[classname]#Select# interface that returns collection of selected items.
You can select an item with the corresponding [methodname]#select()# method.

In multiselect mode, the [methodname]#getSelected()# returns an unmodifiable
set of items. If no item is selected, the select will be an empty collection.

The [classname]#ComboBox# and [classname]#NativeSelect# will show empty
selection when no actual item is selected.


[[components.selection.valuechange]]
== Handling Selection Changes

You can access currently selected item with the [methodname]#getSelected()# or
[methodname]#getFirstSelected()# method of the component. Also, when
handling selection changes with a
[classname]#SelectionChangeListener#, the
[classname]#SelectionChange# will have the selected items of the event.


[source, java]
----
// Create a selection component with some items
ComboBox<String> select = new ComboBox<>("My Select");
select.setItems("Io", "Europa", "Ganymedes", "Callisto");

// Handle selection change
select.addSelectionChangeListener(event ->
    layout.addComponent(new Label("Selected " +
        event.getSelected())));
----

The result of user interaction is shown in
<<figure.components.selection.valuechange>>.

[[figure.components.selection.valuechange]]
.Selected Item
image::img/select-selected1.png[width=30%, scaledwidth=40%]


[[components.selection.newitems]]
== Allowing Adding New Items


[classname]#ComboBox# allows the user to add new items, when the user types
in a value and presses kbd:[Enter]. You need to enable this with
[methodname]#setNewItemHandler()#.

Adding new items is not possible if the selection component is read-only. An
attempt to do so may result in an exception.

[[components.selection.newitems.handling]]
=== Handling New Items

Adding new items is handled by a [interfacename]#NewItemHandler#, which gets the
item caption string as parameter for the [methodname]#addNewItem()# method.

ifdef::web[]

[source, java]
----
// List of planets
List<Planet> planets = new ArrayList<>();
planets.add(new Planet(1, "Mercury"));
planets.add(new Planet(2, "Venus"));
planets.add(new Planet(3, "Earth"));
planets.add(new Planet(4, "Mars"));

ComboBox<Planet> select =
    new ComboBox<>("Select or Add a Planet");
select.setItems(planets);

// Use the name property for item captions
select.setItemCaptionProvider(Planet::getName);

// Allow adding new items and add
// handling for new items
select.setNewItemHandler(inputString -> {

    // Create a new bean - can't set all properties
    Planet newPlanet = new Planet(0, inputString);
    planets.add(newPlanet);

    // Update combobox content
    select.setItems(planets);

    // Remember to set the selection to the new item
    select.select(newPlanet);

    Notification.show("Added new planet called " +
                      inputString);
});
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#component.select.combobox.newitemhandler[on-line example, window="_blank"].
endif::web[]


[[components.selection.multiple]]
== Multiple Selection

Some selection components, such as [classname]#OptionGroup# and
[classname]#ListSelect# support a multiple selection mode, which you can enable
with [methodname]#setSelectionMode(SelectionMode.MULTI)#.
For [classname]#TwinColSelect#, which is especially intended for
multiple selection, it is enabled by default.


[source, java]
----
myselect.setSelectionMode(SelectionMode.MULTI);
----

In multiple selection mode the [interfacename]#Select# value is a
[classname]#Collection# of the items of the currently selected items.
You can get and set the selection with the [methodname]#getSelected()# and
[methodname]#setSelected()# methods as usual.

A change in the selection will trigger a [classname]#SelectionChange#, which
you can handle with a [classname]#SelectionChangeListener#. The
following example shows how to handle selection changes with a listener.


[source, java]
----
// A selection component with some items
ListSelect<String> select = new ListSelect<>("My Selection");
select.setItems("Mercury", "Venus", "Earth",
    "Mars", "Jupiter", "Saturn", "Uranus", "Neptune");

// Multiple selection mode
select.setSelectionMode(SelectionMode.MULTI);

// Feedback on value changes
select.addSelectionChangeListener(event -> {
        // Some feedback
        layout.addComponent(new Label("Selected: " +
            event.getSelected()));
    }
});

----


[[components.selection.item-icons]]
== Item Icons

You can set an icon for each item with [methodname]#setItemIconProvider()#,
in a fashion similar to captions. Notice, however, that icons are not
supported in [classname]#NativeSelect#, [classname]#TwinColSelect#, and
some other selection components and modes. This is because HTML does not
support images inside the native [literal]#++select++#
elements. Icons are also not really visually applicable.