Gathering detailed insights and metrics for ember-event-helpers
Gathering detailed insights and metrics for ember-event-helpers
Gathering detailed insights and metrics for ember-event-helpers
Gathering detailed insights and metrics for ember-event-helpers
Complimentary event template helpers to the {{on}} modifier
npm install ember-event-helpers
Typescript
Module System
Min. Node Version
Node Version
NPM Version
JavaScript (90.42%)
HTML (9.33%)
Handlebars (0.26%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
35 Stars
425 Commits
5 Forks
3 Watchers
18 Branches
5 Contributors
Updated on Jul 01, 2025
Latest Version
0.1.1
Package Id
ember-event-helpers@0.1.1
Size
126.85 kB
NPM Version
6.13.7
Node Version
13.11.0
Published on
Apr 07, 2020
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
27
Complimentary template helpers to be used with the {{on}}
element modifier
specified by RFC #471 "{{on}}
modifier".
ember install ember-event-helpers
If you are below Ember 3.10, you'll also want to install the
{{on}}
modifier polyfill:
ember install ember-on-modifier
Template Helper | Event method |
---|---|
(prevent-default fn) | event.preventDefault() |
(stop-propagation fn | event.stopPropagation() |
(stop-immediate-propagation fn) | stopImmediatePropagation |
???? For usage information on
{{on}}
itself, refer to the RFC or polyfill documentation.
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()
.
Prevent the user agent from performing the default action, like toggling a checkbox, when it is clicked. The event continues to propagate as usual.
1<label> 2 <input type="checkbox" {{on "click" this.onClick}}> 3 Click me baby, one more time! 4</label> 5<label> 6 <input type="checkbox" {{on "click" (prevent-default this.onClick)}}> 7 Can't touch this! 8</label>
1import Component from '@ember/component'; 2import { action } from '@ember/object'; 3 4export default class CheckboxesComponent extends Component { 5 @action 6 onClick(event: MouseEvent) { 7 if (event.defaultPrevented) { 8 console.log('Checkbox will not be toggled.'); 9 } else { 10 console.log('Checkbox will be toggled.'); 11 } 12 } 13}
???? The
@action
decorator is used to bind theonClick
method'sthis
context to the component instance. This is not required here, sincethis
is not accessed, but in order to not break with patterns, we still do it here.
Using the old {{action}}
modifier you would
express the same thing like this:
1<label> 2 <input type="checkbox" {{action this.onClick on="click"}}> 3 Click me baby, one more time! 4</label> 5<label> 6 <input type="checkbox" {{action this.onClick on="click" preventDefault=true}}> 7 Can't touch this! 8</label>
(stop-propagation)
Calls event.stopPropagation()
.
Stops further propagation of the current event in the capturing phase (down the DOM) and bubbling phase (up the DOM).
1<div class="outer" {{on "click" this.onOuterClick}}> 2 <div class="inner-a" {{on "click" this.onInnerClick}}> 3 I bubble. 4 </div> 5 <div class="inner-b" {{on "click" (stop-propagation this.onInnerClick)}}> 6 I don't bubble. 7 </div> 8</div>
1import Component from '@ember/component'; 2import { action } from '@ember/object'; 3 4export default class BubbleGumComponent extends Component { 5 @action 6 onOuterClick(event: MouseEvent) { 7 console.log('outer'); 8 } 9 10 @action 11 onInnerClick(event: MouseEvent) { 12 console.log('inner'); 13 } 14}
Clicking .inner-a
will print:
inner
outer
Clicking .inner-b
will only print:
inner
If you enable the capture
event option and use (stop-propagation)
with it, the event propagation will already be stopped in the capture phase
("down the DOM").
1<div class="outer" {{on "click" (stop-propagation this.onOuterClick)}}> 2 <div class="inner" {{on "click" this.onInnerClick}}> 3 My listener never gets called. 4 </div> 5</div>
Clicking .inner
will only print:
outer
(stop-immediate-propagation)
⚠️ Not implemented yet.
Calls 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.
1<div class="outer" {{on "click" this.onOuterClick}}> 2 <button {{on "click" (stop-propagation this.onInnerClickA)}} {{on "click" this.onInnerClickB}}> 3 Both my listeners get called. 4 </button> 5 <button {{on "click" (stop-immediate-propagation this.onInnerClickA)}} {{on "click" this.onInnerClickB}}> 6 Only my first listener gets called. 7 </button> 8</div>
1import Component from '@ember/component'; 2import { action } from '@ember/object'; 3 4export default class BubbleGumComponent extends Component { 5 @action 6 onOuterClick(event: MouseEvent) { 7 console.log('outer'); 8 } 9 10 @action 11 onInnerClickA(event: MouseEvent) { 12 console.log('inner A'); 13 } 14 15 @action 16 onInnerClickB(event: MouseEvent) { 17 console.log('inner B'); 18 } 19}
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.
If you want to curry the function call / partially apply arguments, you can do
so using the {{fn}}
helper:
1{{#each this.users as |user|}} 2 <button {{on "click" (prevent-default (fn this.deleteUser user))}}> 3 Delete {{user.name}} 4 </button> 5{{/each}}
You can nest the helpers:
1<button {{on "click" (prevent-default (stop-propagation this.onClick))}}> 2 Click me 3</button>
Or register additional "void" helpers, since the fn
argument is optional:
1<button 2 {{on "click" (prevent-default)}} 3 {{on "click" (stop-propagation)}} 4 {{on "click" this.onClick))}} 5> 6 Click me 7</button>
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
57 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More