How to create field widget using Owl in Odoo 16
Widget in Odoo is basically one of the building block of the Odoo User Interface. Odoo has many widgets to perform different functionalities such as remaining_days, color_picker, char_emojis, priority, many2many_tags, boolean_toggle etc.
In Odoo 16 the widgets are migrated to OWL framework. OWL is a
declarative
component system, loosely inspired by Vue and React developed in house by Odoo SA. The work on OWL framework started a few years back and Odoo was slowly migrating various parts of Odoo source code from the old one to the new OWL framework.
In this blog we are discussing about creating widget. Below is the basic step for creating a new widget
For creating a widget we have to first import and extend the component. Components are like functions that returns HTML elements. In Owl we use class components, they are independent and reusable.
1. Import Component from Owl library
/** @odoo-module **/
import { Component } from"@odoo/owl";
2. Import Registry
import { registry } from"@web/core/registry";
3. Extends the component and creates new component class
export class MyNewWidget extends Component {
setup() { // initialize component here
}
}
4. Declaring the template for the widget#The Good practice for naming the template is below because this prevents the collision between Odoo addons MyNewWidget.template = "addon_name.MyNewWidget";
5. Importing standardFieldProps
import { standardFieldProps } from"@web/views/fields/standard_field_props";
MyNewWidget.props = {
...standardFieldProps,
placeholder: { type: String, optional:true },
};
Below are some default standardFieldProps seen in odoo/addons/web/static/src/views/fields/standard_field_props.js
/** @odoo-module **/
export const standardFieldProps = {
id: { type: String, optional:true },
name: { type: String, optional:true },
readonly: { type: Boolean, optional:true },
record: { type: Object, optional:true },
type: { type: String, optional:true },
update: { type: Function, optional:true },
value:true,
decorations: { type: Object, optional:true },
setDirty: { type: Function, optional:true },
};
6. Extract attribute value from props
MyNewWidget.extractProps = ({ attrs }) => {
return {
#this placeholder can be displayed in the template using t-att-placeholder="props.placeholder"
placeholder: attrs.placeholder,
};
};
7. Adding widget display name
MyNewWidget.displayName = _lt("My Widget");
8. Add supported field types for the widget
MyNewWidget.supportedTypes = ["float", "int"];
9. Adding the widget to the registry of category fields
registry.category("fields").add("new_widget", MyNewWidget);
10. Template located in the xml file
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="addon_name.MyNewWidget" owl="1">
<span t-if="props.readonly" t-esc="props.value"/>
<input t-else="" t-att-value="props.value" t-att-placeholder="props.placeholder" class="o_input"/>
</t>
</templates>
11. Add the JS and XML file path to manifest of the module
'assets': { 'web.assets_backend': [ 'module_name/static/src/js/widget_file.js',
'module_name/static/src/xml/widget_file.xml', ]
},
12. Use the widget in a field
<field name="note" widget="new_widget" placeholder="note......."/>
We can also create a new widget by extending the already created widget. Below is the steps for extending the widget.
1. Import the widget that you want to extend
import { MyNewWidget} from"@module_name/static/src/js/MyNewWidget";
2. Extend the imported widget component
exportclass MyNewWidgetExtend extends MyNewWidget {
setup() {
super.setup();
}
}
3. Define the template
MyNewWidgetExtend.template = "module_name.MyNewWidgetExtend"
4. Adding to registry
registry.category("fields").add("new_widget_extend", MyNewWidgetExtend);
5. Template in xml
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="module_name.MyNewWidgetExtend" owl="1">
<span t-if="props.readonly" t-esc="props.value"/>
<input t-else="" t-att-value="props.value" class="o_input"/>
</t>
</templates>
We can create various types of widgets with various functionalities by using the field widgets in Odoo, like triggering a specific action on barcode scan etc.