Event handling enables developers to create interactive and dynamic user interfaces by responding to user actions and system events. It can be something as basic as pressing a button, inputting information in forms, or dropping files into a dropzone area.
Odoo 19 provides developers with the OWL framework, which makes event handling much easier and efficient. With the use of this framework, developers can define the event handling behavior right in the templates, which greatly improves the quality and readability of the code.
Knowing how events work in is very important when developing responsive user interfaces and customizing Odoo modules. This guide explores event handling in the OWL framework, covering its core concepts and practical implementation.
The general syntax for event handling in OWL is:
t-on-<event>="handler"
Example:
<templates>
<t t-name="ClickDemo">
<div>
<button t-on-click="handleClick" class="btn btn-primary">
Click Me
</button>
<p>Clicked: <t t-esc="state.count"/> times</p>
</div>
</t>
</templates>
import { Component, useState } from "@odoo/owl";
export class ClickDemo extends Component {
static template = "ClickDemo";
setup() {
this.state = useState({ count: 0 });
}
handleClick(ev) {
this.state.count++;
}
}Steps to Handle Events in Odoo 19
To handle an event in Odoo 19, follow these steps:
Step 1: Define the event in the template
Add the event binding to the element in your XML template using the t-on- prefix. The value of t-on-click must match exactly the method name defined in the component class.
<templates xml:space="preserve">
<t t-name="MyComponent">
<div class="my-component">
<!-- Bind click event to handler method -->
<button t-on-click="handleClick">Click Me</button>
<p><t t-esc="state.message"/></p>
</div>
</t>
</templates>
Step 2: Define the handler in JavaScript
Write the handler method inside the component class. It automatically receives the native browser Event object as its first argument. OWL automatically binds this to the component instance.
/** @odoo-module **/
import { Component, useState } from "@odoo/owl";
export class MyComponent extends Component {
static template = "MyComponent";
setup() {
this.state = useState({ message: "" });
}
// Event handler method
handleClick(ev) {
// ev = native browser Event object
console.log("Event type:", ev.type); // "click"
console.log("Target element:", ev.target); // <button>
this.state.message = "Button was clicked!";
}
}
Step 3: Pass Arguments to the Handler
When you need to pass extra data (like a record ID), wrap the handler in an arrow function.
<templates xml:space="preserve">
<t t-name="MyComponent">
<div>
<t t-foreach="state.products" t-as="product" t-key="product.id">
<div class="product-card">
<span t-esc="product.name"/>
<!-- Pass product.id as argument -->
<button t-on-click="() => this.handleDelete(product.id)">
Delete
</button>
</div>
</t>
</div>
</t>
</templates>
setup() {
this.state = useState({
products: [
{ id: 1, name: "Product A" },
{ id: 2, name: "Product B" },
{ id: 3, name: "Product C" },
]
});
}
// Receives the passed argument
handleDelete(productId) {
this.state.products = this.state.products.filter(p => p.id !== productId);
console.log(`Deleted product: ${productId}`);
}Event Modifiers
Modifiers change how events behave.
Stops event propagation. Prevents parent elements from receiving the event.
<button t-on-click.stop="onClick"/>
Prevents default browser behavior.
<form t-on-submit.prevent="onSubmit"/>
Prevents page reload.
Here's a comprehensive list of OWL Event Handlers in Odoo 19:
Mouse Events
| Handler | Description |
| t-on-click | Mouse click |
| t-on-dblclick | Double click |
| t-on-mousedown | Mouse button pressed |
| t-on-mouseup | Mouse button released |
| t-on-mousemove | Mouse moved over element |
| t-on-mouseenter | Mouse enters element (no bubble) |
| t-on-mouseleave | Mouse leaves element (no bubble) |
| t-on-mouseover | Mouse over element (bubbles) |
| t-on-mouseout | Mouse out of element (bubbles) |
| t-on-contextmenu | Right-click context menu |
Keyboard Events
| Handler | Description |
| t-on-keydown | Key pressed down |
| t-on-keyup | Key released |
| t-on-keypress | Key pressed |
Form / Input Events
| Handler | Description |
| t-on-change | Input value changed and focus lost |
| t-on-input | Input value changing in real-time |
| t-on-submit | Form submitted |
| t-on-focus | Element gains focus |
| t-on-blur | Element loses focus |
| t-on-focusin | Focus enters element or child (bubbles) |
| t-on-focusout | Focus leaves the element or child (bubbles) |
Drag & Drop Events
| Handler | Description |
| t-on-dragstart | Drag operation starts |
| t-on-dragend | Drag operation ends |
| t-on-dragenter | Dragged element enters target |
| t-on-dragleave | Dragged element leaves the target |
| t-on-dragover | Dragged element over the target |
| t-on-drop | Element dropped on target |
Window / Document Events
| Handler | Description |
| t-on-scroll | Element or page scrolled |
| t-on-load | Resource finished loading |
| t-on-error | Resource failed to load |
Event Handling is a key component of developing interactive applications in Odoo 19. Thanks to OWL's declarative approach, event handling is simplified. Knowing various types of events, such as mouse, keyboard, form, and drag and drop, allows you to design highly interactive interfaces. Moreover, the use of modifiers such as .stop and .prevent lets you control events effectively.
To read more about How to Build Responsive User Interfaces in Odoo 19 with OWL, refer to our blog How to Build Responsive User Interfaces in Odoo 19 with OWL.