Vaadin 8 - Filter several Items from DataProvider

Hello,

I have two TwinColSelects, which are using the same DataProvider.

How can I filter now the already selected items of the available items in both TwinColSelects?
Or in other words: I want on the left side of one TwinColSelect just all items which are also not selected in the other TwinColSelect.

Hope you get my point. In general it would be enough to know, how I can filter several items from a dataprovider.

Thanks!

Anyone a idea?

Nobody who can help me? Please.

Hi, you should use two data providers and add a selection listener on one TwinColSelect to update the other one. Using one data provider for both selects will make them show always the same data. Here’s an example:

List<String> allItems = Arrays.asList("1", "2", "3", "4", "5");

TwinColSelect<String> select1 = new TwinColSelect<>("select1", allItems);
TwinColSelect<String> select2 = new TwinColSelect<>("select2", allItems);

select1.addSelectionListener(e -> {
    Set<String> selectedItems = select1.getSelectedItems();
    List<String> filteredItems = allItems.stream()
            .filter(i -> !selectedItems.contains(i))
            .collect(Collectors.toList());
    select2.setItems(filteredItems);
});

setContent(new VerticalLayout(select1, select2));

Forum tip: Don’t add “answers” to your own question if you want to increase the chances of someone answering your question. There is an “unanswered” option in the forum that shows forum threads with only one entry. Many ppl (including myself) click that option to see who is still waiting for an answer.

Thank you very much Alejandro for your reply.

I have tested your code and I have two questions:

Is it possible to update also the first TwinColSelect when changing the second one?

When .setItems is executed the previous selected items of this TwinColSelect are also gone. How can I prevent that behavior?

Thanks also for the forum tip. Good to know :slight_smile:

Is it possible to update also the first TwinColSelect when changing the second one?

Yes, it is. You might have to use the e.isUserOriginated() method in the listener.

When .setItems is executed the previous selected items of this TwinColSelect are also gone. How can I prevent that behavior?

You can use the TwinColSelect.select method for this.

Here’s an example implementation:

public class MyUI extends UI {

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        List<String> allItems = Arrays.asList("1", "2", "3", "4", "5");

        TwinColSelect<String> select1 = new TwinColSelect<>("select1", allItems);
        TwinColSelect<String> select2 = new TwinColSelect<>("select2", allItems);

        addSelectionListener(allItems, select1, select2);
        addSelectionListener(allItems, select2, select1);

        setContent(new VerticalLayout(select1, select2));
    }

    private void addSelectionListener(List<String> allItems, TwinColSelect<String> select1, TwinColSelect<String> select2) {
        select1.addSelectionListener(e -> {
            if (e.isUserOriginated()) {
                Set<String> selectedItems = select1.getSelectedItems();
                List<String> filteredItems = allItems.stream()
                        .filter(i -> !selectedItems.contains(i))
                        .collect(Collectors.toList());
                Set<String> previouslySelected = select2.getSelectedItems();
                select2.setItems(filteredItems);
                select2.select(previouslySelected.toArray(new String[previouslySelected.size()]
));
            }
        });
    }
}