Enable Dark Mode!
how-to-extend-field-widget-in-odoo-16.jpg
By: Muhsina V

How to Extend Field Widget in Odoo 16

Technical Odoo 16

Odoo provides a wide range of field widgets to display different types of data in the user interface. However, there may be cases where you need to customize an existing field widget or create a new one to meet your specific needs.
Example
Let's create a custom boolean field widget called boolean_badge. This widget will display a badge with the text "Yes" or "No," depending on the value of the field.
To create the widget, we first need to create a new JavaScript file in our module's static/src/js directory. In this file, we will import the standardFieldProps object from the @web/views/fields/standard_field_props module. This object contains a set of standard props that are common to all field widgets. We will also import the Component class from the Owl library.

import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
const { Component } = owl;

Next, we need to define a new class called BooleanBadge that extends the Component class. This class will contain the logic for rendering the badge and handling user interactions.

class BooleanBadge extends Component {

    setup(){
        this.trueValue = 'Yes'
        this.falseValue = 'No'
        this.trueColor = 'green'
        this.falseColor = 'red'
        this.defaultColor = 'white'
    }
    updateValue(val){
        this.props.update(val);
    }
}

In the setup() method, we are setting the default values for the trueValue, falseValue, trueColor, falseColor, and defaultColor props. We can also use the setup() method to initialize any other state that the widget needs.

The updateValue() method is called when the value of the field changes. This method updates the state of the widget and re-renders it.

Now that we have defined the widget class, we need to register it with Odoo. To do this, we add the following code to the end of the JavaScript file.

BoolBadge.template = "BoolBadge"
BoolBadge.props = standardFieldProps
BoolBadge.supportedTypes = ["boolean"]
registry.category("fields").add("boolean_badge",BoolBadge)

The template prop specifies the name of the template file that will be used to render the widget. The props prop specifies the props that are accepted by the widget. The supportedTypes prop specifies the types of fields that the widget can be used with.

Finally, we need to create the template file for the widget. Create a new file in the static/src/xml directory of your module called BooleanBadge.xml. In this file, add the following code:

<?xml version="1.0" encoding="UTF-8" ?>
<templates>
	<t t-name="BooleanBadge" owl="1">
		<span class="badge rounded-pill m-2 p-2 border"
			  t-att-class="props.value ? 'text-white' : 'text-black'
			  t-esc="trueValue"
			  t-attf-style="background-color: {{ props.value ? trueColor : defaultColor}}"
t-on-click="() => this.updateValue(true)"/>
		<span class="badge rounded-pill m-2 p-2 border"
			  t-att-class="props.value ? 'text-black' : 'text-white'"
			  t-esc="falseValue"
			  t-attf-style="background-color: {{ props.value ? defaultColor : falseColor}}"
			  t-on-click="() => this.updateValue(false)"/>
	</t>
</templates>

This template will display a badge with the text "Yes" or "No" depending on the value of the field. The background color of the badge will be determined by the trueColor or falseColor prop, depending on the value of the field.

Once you have created the JavaScript and XML files for the widget, you can use them in your Odoo views. To add the widget to a field, simply add the following attribute to the field:

widget="boolean_badge"

Now, let’s add this widget to the test field inside the product template page.

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <record id="product_template_only_form_view" model="ir.ui.view">
        <field name="name">product.template.inherit.coc</field>
        <field name="model">product.template</field>
        <field name="inherit_id"
               ref="product.product_template_only_form_view"/>
        <field name="arch" type="xml">
            <field name="detailed_type" position="after">
                <field name="test_field" widget="boolean_badge"/>
            </field>
        </field>
    </record>
</odoo>

Now, the field looks like as follows

How to Extend Field Widget in Odoo 16-cybrosys

How to Extend Field Widget in Odoo 16-cybrosys

Extending the BooleanBadge widget to add options

You can extend the BooleanBadge widget to add options that allow you to customize the appearance of the badge and the text that is displayed. For example, you could add an option to change the size of the badge, the font of the badge text, or the border of the badge.

To extend the BooleanBadge widget to add options, you can create a new JavaScript file in the static/src/js directory of your module. Then, Import the BooleanBadge widget from your existing module. Define a new class that extends the BooleanBadge widget. Add a new prop to your widget to store the value of the option. Implement any custom behavior for your option, and register your new widget in the registry module.

Example

/** @odoo-module */
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { BoolBadge } from "@custom_widget/js/bool_badge";
export class CustomBoolBadge extends BoolBadge {
    setup() {
        super.setup();
        const options = this.props.options || {};
        this.trueValue = options.trueValue || 'Yes';
        this.falseValue = options.falseValue || 'No';
        this.trueColor = options.trueColor || 'green';
        this.falseColor = options.falseColor || 'red';
        this.defaultColor = options.defaultColor || 'white';
    }
}
CustomBoolBadge.props = {
    ...standardFieldProps,
    options: { type: Object, optional: true}
}
CustomBoolBadge.extractProps = ({attrs}) => {
    return {options: attrs.options}
}
registry.category("fields").add("custom_bool_badge", CustomBoolBadge);

To use the CustomBoolBadge widget, you can add it to a view in the same way that you would add any other field widget. For example, the following code would add a CustomBoolBadge widget to the test_field field:

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <record id="product_template_only_form_view" model="ir.ui.view">
        <field name="name">product.template.inherit.coc</field>
        <field name="model">product.template</field>
        <field name="inherit_id"
               ref="product.product_template_only_form_view"/>
        <field name="arch" type="xml">
            <field name="detailed_type" position="after">
                <field name="test_field" widget="custom_bool_badge"     options="{'trueColor': 'blue', 'trueValue': 'Yes',
                 'falseColor': 'yellow', 'falseValue': 'No'}"/>
            </field>
        </field>
    </record>
</odoo>

In this, we have given trueColor as blue and falseColor as yellow and corresponding values. Let's see the result.

How to Extend Field Widget in Odoo 16-cybrosysHow to Extend Field Widget in Odoo 16-cybrosys

Now we can see the color has changed to blue and yellow, respectively. 

This is how we can extend and add features to the existing field widgets in Odoo 16.


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



1
Comments

Jitender

Thanks for sharing nice tutorial, How can we extend the template in this case?, lets say I want to add new button in template

16/02/2024

-

10:22AM



Leave a comment



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