Skip to content

feat: make the trigger reachable from item-level events handlers - #802

Merged
bbrala merged 1 commit into
masterfrom
feat/issue-729-trigger-in-item-events
Jul 29, 2026
Merged

feat: make the trigger reachable from item-level events handlers#802
bbrala merged 1 commit into
masterfrom
feat/issue-729-trigger-in-item-events

Conversation

@bbrala

@bbrala bbrala commented Jul 29, 2026

Copy link
Copy Markdown
Member

Problem

Reported in #729: a menu with a text input wants to write the typed value back onto the button that opened the menu, but there was no way to get at the trigger from inside the item's events handler.

What was already possible

Item events handlers are bound with $input.on(item.events, opt), so the menu's options object arrives as jQuery event data. For an item in the root menu that object is the root options object, and op.show() sets $trigger on it, so e.data.$trigger already worked. It was documented in items.md, but the example there was broken (it nested the item under events instead of items), so it was easy to miss.

For an item in a sub-menu the event data is the sub-menu's own options object, and nothing ever set $trigger on it. e.data.$trigger was undefined there.

Change

  • op.setTrigger() stamps the trigger onto the root options object and, recursively, onto the options object of every sub-menu that has already been created. op.show() calls it in place of the old single assignment.
  • op.create() inherits $trigger from the root when it creates a sub-menu, so sub-menus built after the menu was shown (a resolving promise, for instance) get it too.

No handler signature or argument meaning changes: e.data is still the menu's own options object, it just now always carries $trigger.

Docs

  • documentation/docs/items.md: the events section now states what this and e.data are, notes that e.data.$trigger follows the currently visible menu's trigger even when many elements share one menu definition, fixes the broken example, and adds a write-back example.
  • New demo documentation/demo/input-rename-trigger.md with the reporter's exact scenario: two buttons sharing one left-click menu, a text input whose focusout renames the button that was clicked.

Tests

test/unit/issue-729-trigger-in-item-events.test.js:

  • e.data.$trigger resolves to the correct element when two triggers share one menu
  • same for an item in a sub-menu (fails on master)
  • same for a sub-menu built from a promise (fails on master)
  • the reporter's scenario end to end: focusout writes the input value onto the trigger and leaves the other trigger alone

npm test (46 assertions) and the Playwright suite (22) are green, npm run docs:build succeeds.

Closes #729

Item `events` handlers are bound with their menu's options object as jQuery
event data, so `e.data.$trigger` already exposed the trigger for items in the
root menu. Items in a sub-menu got the sub-menu's own options object, which
never had `$trigger` set, leaving no supported way to reach the element that
opened the menu.

op.show() now stamps the trigger onto the root options object and every
already-created sub-menu's options object, and op.create() inherits it from
the root for sub-menus built later (a resolving promise, for instance).

The `events` documentation now spells out what `this` and `e.data` contain,
and its example was fixed: it nested the item under `events` instead of
`items`. Added a demo showing a text input renaming the button that opened
the menu.

Closes #729
@bbrala

bbrala commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

👍

@bbrala
bbrala merged commit 992d9bf into master Jul 29, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make trigger accessible inside event functions

1 participant