Grid
Grid supports single and multi-select modes. Neither is enabled by default.
Single-Selection Mode
In single-selection mode, the user can select and deselect rows by clicking anywhere on the row.
new tab
Grid<Person> grid = new Grid<>(Person.class, false);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
grid.addColumn(Person::getEmail).setHeader("Email");
List<Person> people = DataService.getPeople();
grid.setItems(people);
grid.addSelectionListener(selection -> {
Optional<Person> optionalPerson = selection.getFirstSelectedItem();
if (optionalPerson.isPresent()) {
// System.out.printf("Selected person: %s%n",
// optionalPerson.get().getFullName());
}
});
Multi-Select Mode
In multi-select mode, the user can use a checkbox column to select and deselect more than one row — not necessarily contiguous rows. Or the user can select all rows by clicking on the checkbox in the header row — and then un-check the ones they don’t want to be selected, rather than check many, individually.
new tab
Grid<Person> grid = new Grid<>(Person.class, false);
grid.setSelectionMode(Grid.SelectionMode.MULTI);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
grid.addColumn(Person::getEmail).setHeader("Email");
List<Person> people = DataService.getPeople();
grid.setItems(people);
grid.addSelectionListener(selection -> {
// System.out.printf("Number of selected people: %s%n",
// selection.getAllSelectedItems().size());
});
Range Selection
In addition to selecting rows individually, you may want to allow users to select or deselect a range of rows using Shift + Click. Since there are a variety ways for range selection, Grid provides the necessary event, item-toggle
to create your own implementation. This event provides information about the toggled row, its selection state, and whether the user was holding Shift during the toggle.
The example below demonstrates a possible implementation of range selection using item-toggle
. In this implementation, the first clicked row is stored as an anchor point. When the user holds Shift and clicks another row, the selection state of all rows between the anchor and the newly clicked row is updated to match the clicked row’s state. The second clicked row then becomes the new anchor point for future selections.
new tab
Grid<Person> grid = new Grid<>(Person.class, false);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
grid.addColumn(Person::getEmail).setHeader("Email");
List<Person> people = DataService.getPeople();
grid.setItems(people);
GridMultiSelectionModel<Person> selectionModel = (GridMultiSelectionModel<Person>) grid
.setSelectionMode(Grid.SelectionMode.MULTI);
selectionModel.addClientItemToggleListener(event -> {
Person item = event.getItem();
// If the anchor point isn't set, set it to the current item
if (rangeStartItem == null) {
rangeStartItem = item;
}
if (event.isShiftKey()) {
// Calculcate the range of items between the anchor
// point and the current item
GridListDataView<Person> dataView = grid.getListDataView();
int rangeStart = dataView.getItemIndex(rangeStartItem).get();
int rangeEnd = dataView.getItemIndex(item).get();
Person[] rangeItems = dataView.getItems()
.skip(Math.min(rangeStart, rangeEnd))
.limit(Math.abs(rangeStart - rangeEnd) + 1)
.toArray(Person[]::new);
// Update the selection state of items within the range
// based on the state of the current item
if (event.isSelected()) {
selectionModel.selectItems(rangeItems);
} else {
selectionModel.deselectItems(rangeItems);
}
}
// Update the anchor point to the current item
rangeStartItem = item;
});
A range of rows can also be selected by dragging from one selection checkbox to another, if that’s enabled:
Grid<Person> g = new Grid<>();
g.setSelectionMode(SelectionMode.MULTI);
GridMultiSelectionModel<Person> selectionModel = (GridMultiSelectionModel<Person>)g.getSelectionModel();
selectionModel.setDragSelect(true);
Selection Modes in Flow
Each selection mode is represented by a GridSelectionModel
, accessible through the getSelectionModel()
method, which can be cast that to the specific selection model type, SingleSelectionModel
or MultiSelectionModel
. These interfaces provide selection mode specific APIs for configuration and selection events.
To use Grid with Binder
in Flow, you can use asSingleSelect()
or asMultiSelect()
, depending on the currently defined selection mode. Both methods return interfaces that implement the HasValue
interface for use with Binder
.
Conditional Selection
Grid allows you to configure a predicate to control which rows users may select or deselect. The predicate receives an item and must return true
to allow selection — false
to prevent it. This doesn’t, however, prohibit programmatic selection changes.
Grid<Order> grid = new Grid<>();
// Example predicate that only allows selecting orders that are not complete
grid.setItemSelectableProvider(order -> order.getStatus() != Order.State.COMPLETE);
Note
| In multi-select mode, the Select All checkbox is hidden when using conditional selection. This is because determining the state of the checkbox would require checking all items whenever the selection changes. That could be a performance issue with large data sets or when using lazy data providers. |