I need to show multiple selection combobox in my grid header row to filter grid records.
Currently there is no official multi selection component for Vaadin Flow.
However, you can use the Java integration of the multiselect-combo-box web component for Vaadin Flow. You can see the live demo of the component here.
To use the component, first add the dependency to you pom.xml file (check which is the latest version and modify it accordingly):
<dependency>
<groupId>org.vaadin.gatanaso</groupId>
<artifactId>multiselect-combo-box-flow</artifactId>
<version>0.0.4</version>
</dependency>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
Then instantiate the component and populate it with items:
MultiselectComboBox<String> multiselectComboBox = new MultiselectComboBox();
multiselectComboBox.setLabel("Select items");
multiselectComboBox.setItems("Item 1", "Item 2", "Item 3", "Item 4");
Optionally add a value change listener to get notified when a selection has changed:
multiselectComboBox.addValueChangeListener(e -> {
// get the currently selected items
Set<String> selectedItems = multiselectComboBox.getValue();
});
To use this component as a grid filter, I have modified the example from the Vaadin Grid documentation, and it works as follows:
// setup grid with data provider
List<Person> personList = getItems();
Grid<Person> grid = new Grid<>();
ListDataProvider<Person> dataProvider = new ListDataProvider<>(personList);
grid.setDataProvider(dataProvider);
// add a column
Grid.Column<Person> firstNameColumn = grid.addColumn(Person::getfirstName).setHeader("Name");
HeaderRow filterRow = grid.appendHeaderRow();
// define the multiselect combo box
MultiselectComboBox<String> multiselectComboBox = new MultiselectComboBox();
// set items to list of names
multiselectComboBox.setItems("Jack", "Nathan", "Andrew", "Peter", "Samuel");
// add a value change listener
multiselectComboBox.addValueChangeListener(e -> {
// get the currently selected items
Set<String> selectedItems = multiselectComboBox.getValue();
String names = selectedItems.stream().collect(Collectors.joining(","));
// filter the grid data provider
if (selectedItems.size() > 0) {
dataProvider.addFilter(person -> StringUtils.containsIgnoreCase(person.getfirstName(), names));
} else {
dataProvider.clearFilters();
}
});
// set the component as a filter
filterRow.getCell(firstNameColumn).setComponent(multiselectComboBox);
Hope this helps you achieve your goal!
BR,
Goran
I have integrated existing Polymer component into Vaadin flow:
@Tag("multiselect-combo-box")
@HtmlImport("src/views/common/multiselect-combo-box.html")
public class MultiSelectComboBox extends AbstractCallableComponent {
private List<String> value;
public void setItems(List<String> items) {
JsonArray arr = Json.createArray();
items.forEach(item -> {
arr.set(arr.length(), item);
});
getElement().setPropertyJson("items", arr);
}
@ClientCallable
@Override
public void onValueChange(String s) {
if (s.length() == 0) {
value = Collections.emptyList();
} else {
value = Arrays.stream(s.split(","))
.map(String::trim)
.collect(Collectors.toList());
}
fireEvent(new ChangeEvent(this, false));
}
@Override
public List<String> getValue() {
return value;
}
public Registration addChangeListener(ComponentEventListener<ChangeEvent> listener) {
return addListener(ChangeEvent.class, listener);
}
}
and
public class ChangeEvent extends ComponentEvent<AbstractCallableComponent> {
public ChangeEvent(AbstractCallableComponent source, boolean fromClient) {
super(source, fromClient);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With