Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vaadin flow multiple selection combobox

Tags:

java

vaadin

I need to show multiple selection combobox in my grid header row to filter grid records.

like image 826
Cayman Avatar asked Jan 27 '26 15:01

Cayman


2 Answers

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

like image 185
Goran Avatar answered Jan 30 '26 03:01

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);
    }
}
like image 37
Cayman Avatar answered Jan 30 '26 03:01

Cayman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!