https://github.com/buschtoens/ember-event-helpers
Complimentary event template helpers to the {{on}} modifier
https://github.com/buschtoens/ember-event-helpers
ember ember-addon ember-helper ember-template-helper emberjs events
Last synced: about 1 year ago
JSON representation
Complimentary event template helpers to the {{on}} modifier
- Host: GitHub
- URL: https://github.com/buschtoens/ember-event-helpers
- Owner: buschtoens
- License: mit
- Created: 2019-04-26T11:24:59.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2023-12-15T14:51:18.000Z (over 2 years ago)
- Last Synced: 2025-04-10T13:53:41.141Z (about 1 year ago)
- Topics: ember, ember-addon, ember-helper, ember-template-helper, emberjs, events
- Language: JavaScript
- Homepage:
- Size: 2.55 MB
- Stars: 36
- Watchers: 3
- Forks: 5
- Open Issues: 19
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-ember - ember-event-helpers - Complimentary event template helpers to the `{{on}}` modifier. (Packages / Helpers)
README
# ember-event-helpers
[](https://github.com/buschtoens/ember-event-helpers/actions)
[](http://badge.fury.io/js/ember-event-helpers)
[](http://badge.fury.io/js/ember-event-helpers)
[](https://emberobserver.com/addons/ember-event-helpers)
[](https://travis-ci.org/buschtoens/ember-event-helpers)
[](https://travis-ci.org/buschtoens/ember-event-helpers)
[](https://github.com/prettier/prettier)
[](https://david-dm.org/buschtoens/ember-event-helpers)
[](https://david-dm.org/buschtoens/ember-event-helpers)
Complimentary template helpers to be used with the `{{on}}` element modifier
specified by [RFC #471 "`{{on}}` modifier"][rfc].
[rfc]: https://emberjs.github.io/rfcs/0471-on-modifier.html
## Installation
```
ember install ember-event-helpers
```
If you are below Ember 3.10, you'll also want to install the
[`{{on}}` modifier polyfill][ember-on-modifier]:
```
ember install ember-on-modifier
```
[ember-on-modifier]: https://github.com/buschtoens/ember-on-modifier
#### Compatibility
- Ember.js v2.18 or above
- ember-cli v2.13 or above
## Usage
- **[Template Helpers](#template-helpers)**
- [`(prevent-default fn)`](#prevent-default)
- [`(stop-propagation fn)`](#stop-propagation)
- [`(stop-immediate-propagation fn)`](#stop-immediate-propagation)
- **[Tips & Tricks](#tips--tricks)**
- [Currying / Partial Application](#currying--partial-application)
- [Combining Helpers](#combining-helpers)
- [Getting the `event.target.value`](#getting-the-eventtargetvalue)
> 👉 For usage information on `{{on}}` itself, refer to the [RFC][rfc] or
> [polyfill documentation][ember-on-modifier].
### Template Helpers
| Template Helper | `Event` method |
|----------------------------------------------------------------------|----------------------------------------------------------|
| **[`(prevent-default fn)`](#prevent-default)** | [`event.preventDefault()`][e-preventdefault] |
| **[`(stop-propagation fn)`](#stop-propagation)** | [`event.stopPropagation()`][e-stoppropagation] |
| **[`(stop-immediate-propagation fn)`](#stop-immediate-propagation)** | [`stopImmediatePropagation`][e-stopimmediatepropagation] |
[e-preventdefault]: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
[e-stoppropagation]: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
[e-stopimmediatepropagation]: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation
All three template helpers return a function that, when invoked, will call the
associated `Event` method on the first argument. The helper themselves also take
an optional `fn` argument, which is a function that will be called synchronously
afterwards with all input arguments of the returned function. The return value
of `fn` is passed through.
Sounds complicated? Let's see some examples instead! 😅
#### `(prevent-default)`
Calls [`event.preventDefault()`][e-preventdefault].
Prevent the user agent from performing the default action, like toggling a
checkbox, when it is clicked. The event continues to propagate as usual.
```hbs
Click me baby, one more time!
Can't touch this!
```
```ts
import Component from '@ember/component';
import { action } from '@ember/object';
export default class CheckboxesComponent extends Component {
@action
onClick(event: MouseEvent) {
if (event.defaultPrevented) {
console.log('Checkbox will not be toggled.');
} else {
console.log('Checkbox will be toggled.');
}
}
}
```
> 👉 The [`@action` decorator][@action] is used to bind the `onClick` method's
> `this` context to the component instance. This is not required here, since
> `this` is not accessed, but in order to not break with patterns, we still do
> it here.
[@action]: https://github.com/emberjs/rfcs/blob/master/text/0408-decorators.md#method-binding
Using the old [`{{action}}` modifier][action-event-propagation] you would
express the same thing like this:
```hbs
Click me baby, one more time!
Can't touch this!
```
[action-event-propagation]: https://www.emberjs.com/api/ember/release/classes/Ember.Templates.helpers/methods/action?anchor=action#event-propagation
#### `(stop-propagation)`
Calls [`event.stopPropagation()`][e-stoppropagation].
Stops further propagation of the current event in the capturing phase (down the
DOM) and bubbling phase (up the DOM).
```hbs
I bubble.
I don't bubble.
```
```ts
import Component from '@ember/component';
import { action } from '@ember/object';
export default class BubbleGumComponent extends Component {
@action
onOuterClick(event: MouseEvent) {
console.log('outer');
}
@action
onInnerClick(event: MouseEvent) {
console.log('inner');
}
}
```
Clicking `.inner-a` will print:
```
inner
outer
```
Clicking `.inner-b` will only print:
```
inner
```
If you enable the [`capture` event option][capture] and use `(stop-propagation)`
with it, the event propagation will already be stopped in the capture phase
("down the DOM").
[capture]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters
```hbs
My listener never gets called.
```
Clicking `.inner` will only print:
```
outer
```
#### `(stop-immediate-propagation)`
> ⚠️ Not implemented yet.
Calls [`stopImmediatePropagation`][e-stopimmediatepropagation].
Like `stopPropagation`, but additionally even stopping any further listeners on
the _current_ element in the bubbling / capturing phase to be called.
> 👉 Imagine it like this: `stopPropagation` only stops further propagation
> _vertically_, so further down the DOM (capture phase) or back up the DOM
> (bubble phase). `stopImmediatePropagation` additionally prevents any further
> _horizontal_ propagation, so any further listeners on the same element will
> not be called.
In practice, you will probably never need this helper.
```hbs
Both my listeners get called.
Only my first listener gets called.
```
```ts
import Component from '@ember/component';
import { action } from '@ember/object';
export default class BubbleGumComponent extends Component {
@action
onOuterClick(event: MouseEvent) {
console.log('outer');
}
@action
onInnerClickA(event: MouseEvent) {
console.log('inner A');
}
@action
onInnerClickB(event: MouseEvent) {
console.log('inner B');
}
}
```
Clicking the first button prints:
```
inner A
inner B
```
The listeners are executed in the order they were registered in. The listener on
`.outer` is not called, since the first listener uses `(stop-propagation)`, so
there is no bubbling.
Clicking the second button prints:
```
inner A
```
Since the first listener uses `(stop-immediate-propagation)`, the second
listener is not called. The `.outer` listener is also not called.
### Tips & Tricks
#### Currying / Partial Application
If you want to curry the function call / partially apply arguments, you can do
so using the [`{{fn}}` helper][fn-helper]:
[fn-helper]: https://github.com/emberjs/rfcs/blob/master/text/0470-fn-helper.md
```hbs
{{#each this.users as |user|}}
Delete {{user.name}}
{{/each}}
```
#### Combining Helpers
You can nest the helpers (recommended):
```hbs
Click me
```
Or register additional "void" helpers, since the `fn` argument is optional:
```hbs
Click me
```
Alternatively you could even use [`(queue)` from `ember-composable-helpers`][queue].
[queue]: https://github.com/DockYard/ember-composable-helpers#queue
```hbs
Click me
```
#### Getting the `event.target.value`
With the `{{action}}` modifier / helper, you used to be able to conveniently access
`event.target.value` (or any other property thereof), like so:
```hbs
Click me
```
You can still easily do this with [`(pick)` from `ember-composable-helpers`][pick].
[pick]: https://github.com/DockYard/ember-composable-helpers#pick
```hbs
Click me
```