flow-components
flow-components copied to clipboard
MultiSelectListBox shows incorrect items selected when applying filter to data view
Description
The checkboxes next to selected items don't update when applying a filter to the data view. If indexes 0 and 3 are selected, after applying a filter it still shows 0 and 3 selected even if the items have changed.
Expected outcome
I would expect the correct items to appear selected.
Minimal reproducible example
var comp = new MultiSelectListBox<String>();
comp.setItems("John", "Tim", "Brandon", "Luke", "Kevin");
var filter = new TextField("Filter");
filter.addValueChangeListener(e -> {
var searchPhrase = e.getValue();
var dataView = comp.getListDataView();
dataView.removeFilters();
dataView.addFilter(person ->
StringUtils.isEmpty(e.getValue())
|| StringUtils.containsIgnoreCase(person, searchPhrase));
});
var btn = new Button("Show Selected", e -> {
var names = String.join(",", comp.getSelectedItems());
Notification.show("Selected: " + names)
.setDuration(-1);
});
add(filter, comp, btn);
Steps to reproduce
- Use snippet provided
- Select some names from list
- Enter type into the filter and press 'Enter' key to apply filter
- Optional: click button to display the true selected values
Environment
Vaadin version(s): 23.3.23 OS: MacOS
Browsers
Chrome
This issue has been added to the backlog priority queue for further investigation.
This issue should be fixed by adding refreshAll()
method call to the filter (and sorting maybe) methods in DataView
.
If I add refreshAll()
after modifying the filters, the selection items are completely lost.
filter.addValueChangeListener(e -> {
var searchPhrase = e.getValue();
var dataView = comp.getListDataView();
dataView.removeFilters();
dataView.addFilter(person ->
StringUtils.isEmpty(e.getValue())
|| StringUtils.containsIgnoreCase(person, searchPhrase));
dataView.refreshAll();
});
If I add refreshAll() after modifying the filters, the selection items are completely lost.
@drewharvey Yes, that is a known case, see this ticket https://github.com/vaadin/flow-components/issues/2593
Furthermore, some other components behave same way like CheckBoxGroup, but some others differently, like Grid. Currently the workaround is to get selected items before refreshAll and set the selection programmatically after (as pointed also in the linked ticket).
Since this behavior is sometimes desired and sometimes not, there has been API request to control it https://github.com/vaadin/platform/issues/4486
See also PR https://github.com/vaadin/flow/pull/16650
What is mystery to me is that while this API was already merged and bout be included to Vaadin 24.2, it was reverted, but the revert commit does not explain why @mshabarov ?
It has been reverted because of changed design from having DataProvider methods to a several selection modes on a Component level, see https://github.com/vaadin/platform/issues/4486.
The provided AC ticket has been revised, and there is now an enhancement implementation ticket available at https://github.com/vaadin/flow-components/issues/5744.