flow-components icon indicating copy to clipboard operation
flow-components copied to clipboard

MultiSelectListBox shows incorrect items selected when applying filter to data view

Open drewharvey opened this issue 1 year ago • 6 comments

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.

multiselect-listbox

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

  1. Use snippet provided
  2. Select some names from list
  3. Enter type into the filter and press 'Enter' key to apply filter
  4. Optional: click button to display the true selected values

Environment

Vaadin version(s): 23.3.23 OS: MacOS

Browsers

Chrome

drewharvey avatar Sep 13 '23 21:09 drewharvey

This issue has been added to the backlog priority queue for further investigation.

yuriy-fix avatar Sep 14 '23 15:09 yuriy-fix

This issue should be fixed by adding refreshAll() method call to the filter (and sorting maybe) methods in DataView.

mshabarov avatar Sep 15 '23 06:09 mshabarov

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();
});

list-losing-selection

drewharvey avatar Sep 15 '23 22:09 drewharvey

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 ?

TatuLund avatar Sep 27 '23 05:09 TatuLund

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.

mshabarov avatar Sep 28 '23 10:09 mshabarov

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.

yuriy-fix avatar Dec 04 '23 08:12 yuriy-fix