Enable Dark Mode!
how-to-use-widget-inheritance-in-odoo-19.jpg
By: Safa KB

How to Use Widget Inheritance in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

The frontend of Odoo 19 uses the OWL (Odoo Web Library), which is a framework for developing JS components. The components are designed as modules that can be inherited and extended in order to create customizations without affecting any core files.

There are two methods for implementing widget inheritance:

  • JS Component Inheritance
  • HTML Template Inheritance

1. Inheritance of Widgets Using JavaScript

In JavaScript, inheritance is achieved through the use of the extends keyword to derive a child class from an OWL component.

/** @odoo-module **/
import { OriginalWidget } from "path/to/widget";
import { registry } from "@web/core/registry";
export class CustomWidget extends OriginalWidget {
   setup() {
       super.setup();
       // add your custom logic here
   }
}

Why super.setup() Matters

The setup() function is responsible for setting up state, services, hooks, and handlers. It's important to always call super.setup() first to ensure correct initialization.

Example: Extend CharField to Return Uppercase Values

/** @odoo-module **/
import { CharField } from "@web/views/fields/char/char_field";
import { registry } from "@web/core/registry";
export class UpperCaseField extends CharField {
   setup() {
       super.setup();
   }
   get formattedValue() {
       const val = super.formattedValue;
       return val ? val.toUpperCase() : val;
   }
}
registry.category("fields").add("uppercase_char", {
   component: UpperCaseField,
   displayName: "Uppercase Char",
   supportedTypes: ["char"],
});

Usage in view XML:

<field name="name" widget="uppercase_char"/>

Overriding Methods

Override any parent’s method and invoke super to retain existing functionality:

export class CustomWidget extends OriginalWidget {
   onItemClicked(item) {
       super.onItemClicked(item);
       console.log("Item clicked:", item.id);
   }
}

This is useful for adding validations, logging user actions, showing notifications, or injecting business logic.

2. XML Template Inheritance

XML inheritance changes the component's rendered HTML. OWL templates use t-inherit and t-inherit-mode.

In extension mode, we will include a badge in the many2one container:

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
   <t t-name="my_module.CustomMany2One"
      t-inherit="web.Many2One"
      t-inherit-mode="extension"
      owl="1">
       <xpath expr="//div[hasclass('o_many2one')]" position="inside">
           <span class="badge bg-success ms-2">Verified</span>
       </xpath>
   </t>
</templates>

t-inherit-mode="extension" overrides the existing web.template.Many2One. The badge appears wherever Many2One template is applied.

Primary mode — new template created on the basis of Many2One template (for example, for VIP badge to be shown only for certain values):

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
   <t t-name="my_module.VipMany2One"
      t-inherit="web.Many2One"
      t-inherit-mode="primary"
      owl="1">
       <xpath expr="//div[hasclass('o_field_many2one_selection')]" position="before">
           <span t-if="props.value and props.value[1] and props.value[1].includes('VIP')"
                 class="badge bg-warning text-dark ms-2 fw-bold">
               ? VIP Client
           </span>
       </xpath>
   </t>
</templates>

t-inherit-mode="primary" creates an entirely new template. The original Many2One field on the web does not get impacted by this.

For using this custom template, you need to write a custom JS widget and import this template into it:

/** @odoo-module **/
import { Many2OneField } from "@web/views/fields/many2one/many2one_field";
import { Many2One } from "@web/views/fields/many2one/many2one";
import { registry } from "@web/core/registry";
class VipMany2One extends Many2One {
   static template = "my_module.VipMany2One";
}
class VipMany2OneField extends Many2OneField {
   static components = { Many2One: VipMany2One };
}
registry.category("fields").add("vip_many2one", {
   component: VipMany2OneField,
   displayName: "VIP Many2One",
   supportedTypes: ["many2one"],
});

Asset Registration

Each JS and XML file needs to be registered in __manifest__.py as below:

'assets': {
   'web.assets_backend': [
       'my_module/static/src/js/custom_widget.js',
       'my_module/static/src/xml/custom_widget.xml',
   ],
},

Widget inheritance is one of the most powerful frontend features in Odoo 19. It allows developers to customize existing OWL widgets cleanly without modifying core files.

To read more about Overview of Different Types of Inheritance in Odoo 19, refer to our blog Overview of Different Types of Inheritance in Odoo 19.


Frequently Asked Questions

What is widget inheritance in Odoo 19?

This is the process of inheriting an existing OWL component (JS) and its template (XML) without altering anything in Odoo's core modules.

What is the difference between Extension and Primary Mode?

In extension mode, the original template is modified in a global manner. However, in primary mode, the original template remains intact while creating a new template. In addition, primary mode requires a custom JS widget that makes use of the newly created template.

Why is super.setup() essential?

It helps ensure that the state, services, and other attributes related to the parent component get initialized properly. Without this call, problems may occur.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



Recent Posts

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message