Event Handling ​
Event Handling ​
In a component's template, it is useful to be able to register handlers on DOM elements to some specific events. This is what makes a template alive. This is done with the t-on directive. For example:
<button t-on-click="this.someMethod">Do something</button>This will be roughly translated in javascript like this:
button.addEventListener("click", component.someMethod.bind(component));The suffix (click in this example) is simply the name of the actual DOM event. The value of the t-on expression should be a valid javascript expression that evaluates to a function in the context of the current component. So, one can get a reference to the event, or pass some additional arguments. For example, all the following expressions are valid:
<button t-on-click="this.someMethod">Do something</button>
<button t-on-click="() => this.increment(3)">Add 3</button>
<button t-on-click="ev => this.doStuff(ev, 'value')">Do something</button>Modifiers ​
In order to remove the DOM event details from the event handlers (like calls to event.preventDefault) and let them focus on data logic, modifiers can be specified as additional suffixes of the t-on directive.
| Modifier | Description |
|---|---|
.stop | calls event.stopPropagation() before calling the method |
.prevent | calls event.preventDefault() before calling the method |
.self | calls the method only if the event.target is the element itself |
.capture | bind the event handler in capture mode. |
.synthetic | define a synthetic event handler (see below) |
.passive | bind the handler with the passive option, hinting to the browser that the handler will never call preventDefault(). Useful for scroll and touch* events. |
<button t-on-click.stop="this.someMethod">Do something</button>Note that modifiers can be combined (ex: t-on-click.stop.prevent), and that the order may matter. For instance t-on-click.prevent.self will prevent all clicks while t-on-click.self.prevent will only prevent clicks on the element itself.
Combining .passive with .prevent is contradictory: the browser will ignore preventDefault() calls in a passive listener and log a console warning.
Finally, empty handlers are tolerated as they could be defined only to apply modifiers. For example,
<button t-on-click.stop="">Do something</button>This will simply stop the propagation of the event.
Synthetic Events ​
In some cases, attaching an event handler for each element of large lists has a non trivial cost. Owl provides a way to efficiently improve the performance: with synthetic event, it actually adds only one handler on the document body, and will properly call the handler, just as expected.
The only difference with regular events is that the event is caught at the document body, so it cannot be stopped before it actually gets there. Since it may be surprising in some cases, it is not enabled by default.
To enable it, one can just use the .synthetic suffix:
<div>
<t t-foreach="this.largeList" t-as="elem" t-key="elem.id">
<button t-on-click.synthetic="this.doSomething" ...>
<!-- some content -->
</button>
</t>
</div>On Components ​
The t-on directive also works on a child component:
<div>
in some template
<Child t-on-click="this.doSomething"/>
</div>This will catch all click events on any html element contained in the Child sub component. Note that if the child component is reduced to one (or more) text nodes, then clicking on it will not call the handler, since the event will be dispatched by the browser on the parent element (a div in this case).