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

[combo-box] Add option for auto-focusing first matching item [2 days]

Open fagnercarvalho opened this issue 6 years ago • 11 comments

Description

The vaadin-combo-box element is not selecting the filtered option after tabbing out of the field.

Expected outcome

The current value should be selected when tabbing out.

Actual outcome

The current value is not selected.

Live Demo

There is no live demo for this issue, sorry. However I recorded a short video showing the issue.

Steps to reproduce

  1. Put a vaadin-combo-box element in the page.
  2. Open the page in a web browser.
  3. Search for a valid option in the combo box but don't select this option.
  4. Tab out of the field.

Browsers Affected

  • [X] Chrome (only browser I tested)
  • [ ] Firefox
  • [ ] Safari
  • [ ] Edge
  • [ ] IE 11
  • [ ] iOS Safari
  • [ ] Android Chrome

fagnercarvalho avatar Feb 15 '19 16:02 fagnercarvalho

This would be a very useful feature for heavy data entry applications (not uncommon use for Vaadin), where speed is important. Having to press arrow-down and enter before tabbing to the next field might not sound like much, but the speed with which data entry users fill in forms can really make this a serious workflow bottleneck.

I would propose that this is provided as a setting on the ComboBox, since the described behavior might not always be desired.

rolfsmeds avatar Apr 12 '19 07:04 rolfsmeds

Works for me. Would be nice to see if at least a code snippet to reproduce the issue.

web-padawan avatar Jun 13 '19 10:06 web-padawan

Code is not relevant here -- we're referring to the default standard behavior of the CB, which obviously is not a bug, and should probably remain as the default behavior, but would benefit from an optional mode allowing for faster selection.

User action currently required to select item:

  1. Type into field to filter items
  2. Arrow-down to focus desired item
  3. Tab to blur field -> Focused item is selected

Desired optional mode to select an item:

  1. Type into field to filter until only one item is available
  2. Tab to blur field -> Only available item is selected

Alternately, this could even be:

  1. Type into field to filter items
  2. Tab to blur field -> First available item is selected

rolfsmeds avatar Jun 14 '19 06:06 rolfsmeds

Type into field to filter until only one item is available

I see. Now it only gets selected once you entered all the characters. Otherwise, it isn't.

web-padawan avatar Jun 14 '19 06:06 web-padawan

Proposal:

  • Let's add an API to the combox called autoFocusFirstMatch
  • When enabled, the topmost match is automatically focused when the filter text is changed and non-empty
  • Contrary to manual focusing of list items (e.g. with arrow keys), the input field text is neither updated to match it, nor selected
  • When allowCustomValue is enabled, this the autofocus setting is ignored (i.e. default behavior is used).

rolfsmeds avatar Mar 03 '20 14:03 rolfsmeds

Adding a simple workaround here that should enable the basic use case while waiting for the final implementation.

public class AutoComboBox<T> extends ComboBox<T> {

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        this.getElement().getNode().runWhenAttached((ui) -> {
            ui.beforeClientResponse(this, (context) -> {
                ui.getPage().executeJs("$0.addEventListener('filter-changed', () => {setTimeout(() => {$0._focusedIndex = 0;});});", new Serializable[]{this.getElement()});
            });
        });
    }
}

mhosio avatar Mar 19 '20 07:03 mhosio

There is a component in the directory that mimics this behavior. Just for reference, the modifications over the original combobox for achieving this are in here.

mlopezFC avatar Jan 05 '22 18:01 mlopezFC

Adding a simple workaround here that should enable the basic use case while waiting for the final implementation.

public class AutoComboBox<T> extends ComboBox<T> {

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        this.getElement().getNode().runWhenAttached((ui) -> {
            ui.beforeClientResponse(this, (context) -> {
                ui.getPage().executeJs("$0.addEventListener('filter-changed', () => {setTimeout(() => {$0._focusedIndex = 0;});});", new Serializable[]{this.getElement()});
            });
        });
    }
}

Some troubles with large data set. This works:

        ComboBox<String> comboBox = new AutoComboBox<String>();
        comboBox.setItems(Stream.generate(() -> RandomStringUtils.randomAlphabetic(10)).limit(10));

This not:

        ComboBox<String> comboBox = new AutoComboBox<String>();
        comboBox.setItems(Stream.generate(() -> RandomStringUtils.randomAlphabetic(10)).limit(1000));

If i add a second parameter 1000 to setTimeout, then it work, but with delays.

lanmaster avatar Dec 19 '22 12:12 lanmaster

The issue is timeboxed to research if the solution is feasible. Automatic selection of the first item won't be a good idea, but autofocusing the first item should be considered. No item will be focused till the items are loaded. User would need to wait before proceeding to the next field. (in most cases that would be a matter of ms)

yuriy-fix avatar Aug 15 '24 13:08 yuriy-fix

We implemented a workaround to focus the first item automatically, and our users love it

leluna avatar May 26 '25 10:05 leluna

Contrary to manual focusing of list items (e.g. with arrow keys), the input field text is neither updated to match it, nor selected

Updating the input text value and selection to match can only work if starts-with filtering is used. But in that particular case, updating the input value to match and selecting the autocompleted part of it would be a nice visual confirmation that the first matching item will be selected when you tab out of the field.

Image

jouni avatar May 27 '25 08:05 jouni

There are two competing behavior proposals for this:

  • Autoselect the first matching item
  • Autoselect the only matching item if there is exactly one (see #9636)

I suppose the API for enabling this behavior could allow for selecting between these two, e.g. like this in Flow

setAutoSelect(AutoSelectBehavior.FIRST_MATCH);
setAutoSelect(AutoSelectBehavior.ONLY_MATCH);

rolfsmeds avatar Sep 08 '25 19:09 rolfsmeds