Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f78f032

Browse files
committed
Pass the ActionEvent (with params) to registerActionOption callbacks
- Add ability for registerActionOption callbacks to receive the event after `params` have been resolved - Relates to #668
1 parent b73bef7 commit f78f032

3 files changed

Lines changed: 53 additions & 13 deletions

File tree

docs/reference/actions.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ The list of supported modifier keys is shown below.
131131

132132
Sometimes a controller needs to listen for events dispatched on the global `window` or `document` objects.
133133

134-
You can append `@window` or `@document` to the event name (along with any filter modifier) in an action descriptor to install the event listener on `window` or `document`, respectively, as in the following example:
134+
You can append `@window` or `@document` to the event name (along with any filter modifer) in an action descriptor to install the event listener on `window` or `document`, respectively, as in the following example:
135135

136136
<meta data-controller="callout" data-callout-text-value="resize@window">
137137

@@ -215,12 +215,12 @@ route the event to the controller action, return `true`.
215215

216216
The callback accepts a single object argument with the following keys:
217217

218-
Name | Description
219-
--------|------------
220-
name | String: The option's name (`"open"` in the example above)
221-
value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`)
222-
event | [Event][]: The event instance
223-
element | [Element]: The element where the action descriptor is declared
218+
| Name | Description |
219+
| ------- | ----------------------------------------------------------------------------------------------------- |
220+
| name | String: The option's name (`"open"` in the example above) |
221+
| value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`) |
222+
| event | [Event][]: The event instance, including with the `params` action parameters on the submitter element |
223+
| element | [Element]: The element where the action descriptor is declared |
224224

225225
[toggle]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLDetailsElement/toggle_event
226226
[Event]: https://developer.mozilla.org/en-US/docs/web/api/event

src/core/binding.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ export class Binding {
2929
}
3030

3131
handleEvent(event: Event) {
32-
if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(event)) {
33-
this.invokeWithEvent(event)
32+
const actionEvent = this.prepareActionEvent(event)
33+
if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
34+
this.invokeWithEvent(actionEvent)
3435
}
3536
}
3637

@@ -65,12 +66,14 @@ export class Binding {
6566
return passes
6667
}
6768

68-
private invokeWithEvent(event: Event) {
69+
private prepareActionEvent(event: Event): ActionEvent {
70+
return Object.assign(event, { params: this.action.params })
71+
}
72+
73+
private invokeWithEvent(event: ActionEvent) {
6974
const { target, currentTarget } = event
7075
try {
71-
const { params } = this.action
72-
const actionEvent: ActionEvent = Object.assign(event, { params })
73-
this.method.call(this.controller, actionEvent)
76+
this.method.call(this.controller, event)
7477
this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName })
7578
} catch (error: any) {
7679
const { identifier, controller, element, index } = this

src/tests/modules/core/event_options_tests.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@ export default class EventOptionsTests extends LogControllerTestCase {
213213
this.assertActions({ name: "log", eventType: "toggle" })
214214
}
215215

216+
async "test custom action option callback event contains params"() {
217+
let lastActionEventParams: Object = {}
218+
219+
// clone the params to ensure we check the value as the callback receives it
220+
// not the event after all actions have resolved
221+
222+
const mockCallback = ({ event: { params = {} } = {} }) => {
223+
lastActionEventParams = { ...params }
224+
}
225+
226+
this.application.registerActionOption("all", (options: Object) => {
227+
mockCallback(options)
228+
return true
229+
})
230+
231+
this.buttonElement.setAttribute("data-c-custom-number-param", "41")
232+
this.buttonElement.setAttribute("data-c-custom-string-param", "validation")
233+
this.buttonElement.setAttribute("data-c-custom-boolean-param", "true")
234+
this.buttonElement.setAttribute("data-d-should-ignore-param", "_IGNORED_")
235+
236+
await this.setAction(this.buttonElement, "click->c#log:all")
237+
238+
await this.triggerEvent(this.buttonElement, "click")
239+
240+
this.assertActions({ name: "log", identifier: "c", eventType: "click", currentTarget: this.buttonElement })
241+
242+
const expectedEventParams = {
243+
customBoolean: true,
244+
customNumber: 41,
245+
customString: "validation",
246+
}
247+
248+
this.assert.deepEqual(this.controllerConstructor.actionLog[0].params, expectedEventParams)
249+
250+
this.assert.deepEqual(lastActionEventParams, expectedEventParams)
251+
}
252+
216253
setAction(element: Element, value: string) {
217254
element.setAttribute("data-action", value)
218255
return this.nextFrame

0 commit comments

Comments
 (0)