Odoo 17’s modern frontend framework, OWL (Odoo Web Library), makes it easy to create dynamic and interactive user interfaces. One common requirement is to add a Many2one selection field in a custom dialog popup, allowing users to select a record (e.g., a product from product.product) from a related model. In this blog, we’ll walk through the process of implementing a Many2one field in a custom dialog popup using OWL in Odoo 17, based on a provided code example. This tutorial is perfect for developers looking to enhance their Odoo modules with modern, responsive popups.
Why Use a Many2one Field in a Dialog Popup?
A Many2one field in Odoo links a record to a single record from another model, such as selecting a product for an order or a customer for a task. When integrated into a dialog popup, it provides a user-friendly dropdown or search-enabled interface, ideal for scenarios like:
- Selecting a product in a wizard for order processing.
- Assigning a category or partner in a custom form.
- Streamlining data entry in a popup interface.
In this tutorial, we’ll create a custom dialog popup that allows users to select a product (product.product) using a Many2one field, styled beautifully with OWL and triggered via a client action.
Prerequisites
Before we begin, ensure you have:
- Odoo 17 installed and running.
- Basic knowledge of Odoo module development, including Python, XML, and JavaScript (OWL).
- A custom module created. We’ll assume it’s named your_module.
- Familiarity with OWL components and Odoo’s Many2XAutocomplete widget for relational fields.
Let’s dive into the implementation!
Step 1: Set Up the OWL Component
The core of the dialog popup is an OWL component that renders the Many2one field using the Many2XAutocomplete widget. This widget provides a searchable dropdown for selecting records from a related model. Below is the JavaScript code for the OWL component.
/** @odoo-module **/
import { useService } from "@web/core/utils/hooks";
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Many2XAutocomplete } from "@web/views/fields/relational_utils";
export class Many2oneModal extends Component {
setup() {
this.state = useState({
value: 'Select A Value'
});
}
async update(selection) {
this.state.value = selection[0]?.display_name || 'Select A Value';
}
getDomain() {
return [["active", "=", true]];
}
}
Many2oneModal.components = { Many2XAutocomplete };
Many2oneModal.template = "your_module.Many2oneModal";
registry.category("actions").add("Many2oneModal", Many2oneModal);
Breakdown of the Code:
- Imports:
- useService: Allows access to Odoo services (e.g., ORM, notification).
- Component, useState: OWL utilities for creating reactive components.
- registry: Registers the component as a client action.
- Many2XAutocomplete: Odoo’s widget for rendering Many2one and Many2many fields with autocomplete functionality.
- Class Definition:
- Many2oneModal extends Component to define the popup’s logic.
- setup() initializes a reactive state object with a value property to store the selected product’s display name.
- Methods:
- update(selection): Updates the state.value with the selected product’s display name (or resets to 'Select A Value' if no selection is made).
- getDomain(): Defines a domain to filter records (e.g., only active products).
- Configuration:
- Many2oneModal.components includes Many2XAutocomplete for use in the template.
- Many2oneModal.template links to the XML template your_module.Many2oneModal.
- registry.category("actions").add registers the component as a client action with the tag Many2oneModal.
Improvement Tip: Consider adding a confirmation action to save the selected value to a model or perform additional logic. For example, you could use useService("orm") to write the selected product to a record.
Step 2: Define the OWL Template
The OWL template defines the popup’s UI, including the Many2one field rendered via Many2XAutocomplete. The provided XML template is clean and styled for a professional look.
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="your_module.Many2oneModal">
<div style="padding: 1rem;">
<label for="productSelect" style="display:block; font-weight:600; margin-bottom:0.5rem; color:#333;">
Select Products
</label>
<div id="productSelect" style="padding: 0.5rem; background:#f9f9f9; border-radius:0.5rem;">
<Many2XAutocomplete
value="state.value"
resModel="'product.product'"
fieldString="'Field'"
getDomain.bind="getDomain"
update.bind="update"
activeActions="{}"
isToMany="false"
/>
</div>
</div>
</t>
</templates>
Breakdown of the Template:
- Structure:
- The <t t-name="your_module.Many2oneModal"> defines the template for the Many2oneModal component.
- A <div> with padding wraps the content for spacing.
- Label:
- A <label> with inline styles (font-weight:600, color:#333) provides a clear, bold title for the Many2one field.
- Many2XAutocomplete:
- value="state.value": Binds the field’s display value to the component’s state.value.
- resModel="'product.product'": Specifies the target model for the Many2one field.
- fieldString="'Field'": Sets the label for the field (consider renaming to something descriptive like 'Product').
- getDomain.bind="getDomain": Binds the getDomain method to filter records.
- update.bind="update": Binds the update method to handle selection changes.
- activeActions="{}": Disables actions like creating or opening records (customizable as needed).
- isToMany="false": Specifies this is a Many2one field, not Many2many.
- Styling:
- The <div id="productSelect"> has a light
System: light background with a subtle border, and a clean, readable font like Roboto or Open Sans.
Adding a Many2one selection field to a custom dialog popup in Odoo 17 using OWL is a powerful way to create dynamic, user-friendly interfaces. By leveraging the Many2XAutocomplete widget, you can seamlessly integrate a searchable dropdown for selecting records, such as products, in a stylish popup. The provided code demonstrates a clean implementation with a reactive OWL component, a well-styled template, and a client action to trigger the popup. With these steps, you can enhance your Odoo module’s functionality, streamline user interactions, and deliver a professional user experience. Experiment with additional features like saving selections or customizing the domain to tailor the pop-up to your specific needs.
To read more about How to Add a Many2many Selection Field in a Custom Dialog Popup in Odoo 17 Using OWL, refer to our blog How to Add a Many2many Selection Field in a Custom Dialog Popup in Odoo 17 Using OWL.