Creating custom field components in Odoo 17 allows developers to tailor the user interface to specific business needs, enhancing functionality and user experience. Whether you're adding a specialized input like a month picker or a custom widget, Odoo’s modular architecture makes it straightforward. In this guide, we’ll walk through creating a new InputMonth field component in Odoo 17, complete with JavaScript and XML code, to help you seamlessly extend your Odoo applications.
Prerequisites
Before diving in, ensure you have:
- Odoo 17 is installed, and a development environment is set up.
- Basic knowledge of JavaScript, OWL (Odoo’s Web Library), and XML.
- A custom module where you’ll add the new field component.
Step 1: Define the JavaScript Component
The first step is to create a JavaScript file that defines the new field component. This component will handle the logic for rendering and interacting with the InputMonth field.
JavaScript Code
Create a file, e.g., static/src/js/input_month.js, with the following content:
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
import { useInputField } from "@web/views/fields/input_field_hook";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { Component } from "@odoo/owl";
export class InputMonth extends Component {
static template = "your_module_name.InputMonth";
static props = {
...standardFieldProps,
placeholder: { type: String, optional: true },
};
setup() {
useInputField({ getValue: () => this.props.record.data[this.props.name] || "" });
}
}
export const month = {
component: InputMonth,
displayName: _t("month"),
supportedTypes: ["char"],
extractProps: ({ attrs }) => ({
placeholder: attrs.placeholder,
}),
};
registry.category("fields").add("month", month);
Explanation:
- The InputMonth class extends Component from OWL, defining the behavior of the new field.
- static template points to the XML template (your_module_name.InputMonth) that renders the field.
- useInputField hook ensures the input field syncs with Odoo’s data model.
- The component is registered in the fields category with the name month, making it available for use in views.
Step 2: Create the XML Template
Next, define the XML template to control how the field is rendered in the UI. This template handles both read-only and editable modes.
XML Template
Create a file, e.g., static/src/xml/input_month.xml, with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="your_module_name.InputMonth">
<div class="o_phone_content d-inline-flex w-100">
<t t-if="props.readonly">
<a t-if="props.record.data[props.name]" class="o_form_uri" target="_blank" t-esc="props.record.data[props.name]"/>
</t>
<t t-else="">
<input
class="o_input"
t-att-id="props.id"
type="month"
autocomplete="off"
t-att-placeholder="props.placeholder"
t-ref="input"
/>
</t>
</div>
</t>
</templates>
Explanation:
* The template uses OWL’s <t> tags to conditionally render the field.
* In read-only mode (props.readonly), it displays the field value as a link (if applicable).
* In edit mode, it renders an HTML input element with type="month", allowing users to select a month and year.
Step 3: Register the Assets in Your Module
To ensure Odoo loads the JavaScript and XML files, update your module’s manifest file (__manifest__.py) to include the assets.
Manifest Update
'assets': {
'web.assets_backend': [
'your_module_name/static/src/js/input_month.js',
'your_module_name/static/src/xml/input_month.xml',
],
},
Replace your_module_name with the name of your custom module.
Step 4: Use the New Field in a View
Now, you can use the month field in your Odoo views. Add it to a model’s form view by updating the XML view definition.
Example Form View
<field name="month_field" widget="month"/>
Explanation:
- month_field is the field name defined in your model (e.g., a Char field).
- widget="month" tells Odoo to use the custom month field component.
Step 5: Add the Field to Your Model
Ensure your model includes a field compatible with the month widget (e.g., a Char field to store the month value).
Python Model
from odoo import fields, models
class YourModel(models.Model):
_name = 'your.model'
_description = 'Your Model Description'
month_field = fields.Char(string='Month')
Step 6: Test Your Component
- Install or upgrade your custom module.
- Open a form view where the month_field is used.
- Verify that the field renders as a month picker in edit mode and displays correctly in read-only mode.
Conclusion
Adding a custom field component like InputMonth in Odoo 17 is a powerful way to enhance your application’s functionality. By leveraging OWL, Odoo’s registry, and XML templates, you can create tailored input fields that meet specific requirements. This example demonstrates a simple month picker, but the same principles apply to more complex components. Experiment with Odoo’s framework to build intuitive, user-friendly interfaces for your business needs!
To read more about How to Add Fields to a New View in Odoo 17 , refer to our blog How to Add Fields to a New View in Odoo 17.