Skip to content

Autocomplete/combobox suggestion requires a double tap to select on touch devices (single tap is lost) #26919

@Anexus5919

Description

@Anexus5919

Jenkins and plugins versions report

Pre-existing on current master (verified at master 063b6a7, Jenkins 2.568+); present in recent weeklies/LTS that ship the tippy.js-based dropdowns (src/main/js/components/dropdowns, tippy.js 6.3.7). Not introduced by #26884 (that PR only changed the tippy appendTo target; this race exists regardless of where the popper is appended). Client-side / web-UI only; no plugins required to reproduce.

What Operating System are you using (both controller, and any agents involved in the problem)?

Controller OS is irrelevant (client-side). Reproduces in any modern browser on a touch-capable input: a laptop touchpad with tap-to-click, a touchscreen, or browser DevTools touch emulation. A conventional mouse does not reproduce.

Reproduction steps

  1. Open /newJob (New Item). Choose "Copy existing item" / "Duplicate existing" and focus the "Copy from" field (an INPUT.auto-complete). Type a prefix so multiple suggestions appear. (The INPUT.combobox2 field at /project-relationship behaves identically.)
  2. Using a touchpad tap or touchscreen tap (not a physical mouse button, not the keyboard), single-tap one of the suggestions.

Expected Results

A single tap selects the suggestion and fills the field, identical to a single mouse click or pressing Enter on a keyboard-highlighted item.

Actual Results

The first tap dismisses the suggestion list without selecting anything; a second tap is required to select. A single mouse click and keyboard Enter both work on the first interaction.

Anything else?

Root cause, verified against the source:

The input registers a focusout handler that hides the dropdown on a fixed 200 ms timer:

  • src/main/js/components/dropdowns/autocomplete.js:103-105
    // otherwise menu won't hide on tab with nothing selected
    // needs delay as without that it blocks click selection of an item
    e.addEventListener("focusout", () =>
      setTimeout(() => e.dropdown && e.dropdown.hide(), 200),
    );
  • src/main/js/components/dropdowns/combo-box.js:81-83 has the same pattern.

A dropdown item's selection is wired only to the click event (no mousedown/pointerdown/touchend listener): src/main/js/components/dropdowns/templates.js:247 (element.addEventListener("click", opt.onClick)), where opt.onClick is the confirm() closure (autocomplete.js:14-20, combo-box.js:6-10).

Event sequence on a touch tap:

  1. Tap fires touchstart/touchend; focus leaves the input, so focusout schedules dropdown.hide() at now + 200 ms.
  2. The browser synthesizes mousedown/mouseup/click only after the platform's synthetic-click latency (~300 ms; on touchpads similarly > 200 ms).
  3. At ~200 ms the timer fires tippy.hide(), which synchronously sets the popper to visibility: hidden (and unmounts it ~250 ms later via animation: "dropdown", duration: 250, templates.js:38-39).
  4. At ~300 ms the synthesized click arrives, but the item is already hidden/unmounted, so the click listener (templates.js:247, which runs confirm()) never fires. The first tap is lost; the second tap (field re-focused, list re-shown) selects.

Why mouse works: mousedown and click fire essentially synchronously (under 200 ms), so confirm() runs before the timer (the in-code comment notes the delay exists "as without that it blocks click selection of an item").
Why keyboard works: src/main/js/util/keyboard.js:71-74 calls selectedItem.click() directly on Enter, which is synchronous, with no pointer hit-testing and no focusout.
Not a tippy issue: the popper is interactive: true (templates.js:29), so tippy's own onDocumentPress is exempt for presses inside the popper; the decisive teardown is the app-level 200 ms focusout timer, which is simply shorter than the platform's synthetic-click delay.

Affects both INPUT.auto-complete and INPUT.combobox2. No automated coverage: test/src/test/java/lib/form/ComboBoxTest.java is HtmlUnit-based and cannot synthesize touch-to-mouse timing, so this must be verified manually on a touch device.

Are you interested in contributing a fix?

Yes. A fix should distinguish focus leaving the field entirely (Tab/blur, which should hide) from focus leaving into a tap on a suggestion (which must not pre-empt the click), for example by selecting on pointerdown/mousedown, or by cancelling the pending hide when a tap lands on an item.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions