How to Create a Custom Dialog with Many2many Record Selector in Odoo 17 Using OWL

Introduction

Looking to enhance your Business Management ERP experience with a custom and intuitive record selection popup? In this guide, you’ll learn how to build a Many2many selection field within a custom dialog popup using the OWL (Odoo Web Library) framework in Odoo 17.

Whether you need a product picker for sales orders or a multi-record selector for custom modules, this tutorial gives you a clean, scalable solution with step-by-step instructions. Let’s dive in and make your Odoo UI smarter and more user-friendly!


Prerequisites

Make sure you have the following before proceeding:

  • Odoo 17 Community or Enterprise installed and running.

  • Basic understanding of OWL and Odoo module development.

  • Your custom module structure is set up with JavaScript, XML, and client actions.


Step-by-Step Implementation

1. JavaScript Component (multiselection.js)

Defines the OWL component and handles record selection logic.

/** @odoo-module **/
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { Component, useState } from "@odoo/owl";
import { MultiRecordSelector } from "@web/core/record_selectors/multi_record_selector";
export class Multiselection extends Component {
static template = ‘your_module_name.multiselection’;
static components = { MultiRecordSelector };

setup() {
this.nameService = useService(“name”);
this.relationState = useState({
defaultValue: [],
displayNames: [],
relatedModel: {
label: undefined,
technical: ‘product.template’,
},
});
}

get domain() {
return [[“active”, “=”, false]]; // You can modify as needed
}

async onValuesSelected(resIds) {
const displayNames = await this.nameService.loadDisplayNames(
this.relationState.relatedModel.technical,
resIds
);
this.relationState.defaultValue = resIds;
this.relationState.displayNames = Object.values(displayNames);
}
}

registry.category(“actions”).add(“Multiselection”, Multiselection);


2. OWL Template (multiselection.xml)

Defines the layout and structure of the dialog box.

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="your_module_name.multiselection">
<MultiRecordSelector
resModel="relationState.relatedModel.technical"
resIds="relationState.defaultValue || []"
t-key="relationState.relatedModel.technical"
domain="domain"
placeholder="'Choose Products'"
fieldString="'Products'"
update.bind="onValuesSelected"
/>
</t>
</templates>

3. Client Action (client_action.xml)

Triggers the popup from a view like sale.order.

<record id="choose_product_action" model="ir.actions.client">
<field name="name">Choose Product</field>
<field name="tag">Multiselection</field>
<field name="binding_model_id" ref="sale.model_sale_order"/>
<field name="target">new</field>
</record>

How to Integrate

1. Module Structure

Ensure your module follows this layout:

your_module_name/
├── static/
│ └── src/
│ ├── js/
│ │ └── multiselection.js
│ └── xml/
│ └── multiselection.xml
├── views/
│ └── client_action.xml
├── __manifest__.py

2. Update __manifest__.py

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

3. Install or Upgrade

Install or upgrade your module in Odoo to register and activate the new client action.


Testing Your Dialog

  1. Go to Sales > Orders.

  2. Use the client action (e.g., via a button or menu) to trigger the “Choose Product” popup.

  3. The dialog will show a list of inactive products (per the domain).

  4. Select multiple records; their display names and IDs will be stored in the component state.


Customizations & Use Cases

  • Change the Model: Update product.template to another model (e.g., res.partner).

  • Modify the Domain: Customize the domain logic for your use case, e.g., [['customer_rank', '>', 0]].

  • Add Backend Logic: Save selected resIds to a model or trigger additional logic.

  • Styling: Enhance the visual design via custom CSS or additional OWL components.


Conclusion

By integrating a Many2many selection field within a custom dialog popup using OWL in Odoo 17, you’re empowering your ERP with highly interactive UI elements.

The use of MultiRecordSelector makes it efficient and user-friendly, and with a few tweaks, you can adapt this solution to various business needs across your Business Management ERP modules.

Book an Implementation consultant today.

Leave a Reply

Your email address will not be published. Required fields are marked *