Skip to content

Multi-Select Combo Box Overlay not updating correctly after refocusing #8183

@RSM-SLU

Description

@RSM-SLU

Description of the bug

When using a Multi-Select Combo Box with only custom values, the overlay fails to update correctly after the component has lost focus and then regained it.
The list of selections will show duplicate ghost items, based on which items were selected before focus was regained:
ghost items
Here, the "3" item was added after regaining focus. Selecting a ghost choice might result in NullPointerException: Cannot provide an id for a null item.
The field can be "reset" by deleting all choices and losing and regaining focus again. Probably, because the initial list of choices (which would be duplicated) is then empty again.

Expected behavior

The overlay should update correctly, the same as before it loses focus. Before the focus is lost item can be both added and deleted, with the overlay staying up-to-date.

Minimal reproducible example

@Route
public class MainView extends VerticalLayout {
    public MainView() {
        final ArrayList<String> searchTerms = new ArrayList<>();
        final AtomicBoolean ignoreValueChangeListener = new AtomicBoolean(false);

        final MultiSelectComboBox<String> searchTermsComboBox = new MultiSelectComboBox<>("Search terms");
        searchTermsComboBox.setSelectedItemsOnTop(true);
        searchTermsComboBox.setAutoExpand(MultiSelectComboBox.AutoExpandMode.BOTH);

        // When entering a new search string, add it to the list of selected search strings
        searchTermsComboBox.addCustomValueSetListener(e -> {
            final String newTerm = e.getDetail();
            if (!searchTerms.contains(newTerm)) {
                ignoreValueChangeListener.set(true); // Temporarily ignore value change listener
                searchTerms.add(newTerm);
                // Update the items in the ComboBox to include the new term
                searchTermsComboBox.setItems(searchTerms);
                searchTermsComboBox.select(searchTerms);
                ignoreValueChangeListener.set(false);
            }
        });
        // Handle deselection of search terms
        searchTermsComboBox.addValueChangeListener(e -> {
            if (ignoreValueChangeListener.get()) {
                return; // Ignore the listener if we are currently updating items
            }

            ignoreValueChangeListener.set(true); // Temporarily ignore value change listener to update items
            final Set<String> selectedTerms = e.getValue();
            searchTerms.removeIf(term -> !selectedTerms.contains(term));
            searchTermsComboBox.setItems(searchTerms);
            searchTermsComboBox.select(searchTerms);

            ignoreValueChangeListener.set(false);
        });
        add(searchTermsComboBox);
    }
}

Versions

  • Vaadin / Flow version: 24.4.8
  • Java version: 17
  • OS version: Windows 10
  • Browser version (if applicable): Tested in Firefox and Chrome (both up-to-date)
  • Application Server (if applicable): (Spring Boot)
  • IDE (if applicable): (IntelliJ)

Metadata

Metadata

Assignees

Type

No type

Projects

Status

✅ Closed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions