Creating Advanced Selection Fields in Odoo 18 with Select2
Standard HTML select boxes in Odoo forms are functional but functionally limited. When you need to offer a premium user experience—like searching through hundreds of options, grouping items, or limiting multi-selections—the native widget falls short.
Enter Select2. This powerful JavaScript library transforms standard select boxes into advanced, searchable, and highly customizable input fields. In this tutorial, we will build a Restaurant Reservation Form in Odoo 18 where customers can select their "Dietary Preferences" using a rich Select2 interface with grouping and selection limits.
Why Select2?
- Searchable: Users can type to find options instantly.
- Multi-Select Tags: Selected items appear as clear, dismissible tags.
- Grouped Data: Organize complex lists (e.g., Allergies vs. Diets) for better readability.
Step 1: Load Assets
First, we need to inject the Select2 library into Odoo's frontend assets. While you can bundle the library, using a reliable CDN is often the quickest way to get started for website modules.
'assets': {
'web.assets_frontend': [
# Select2 CSS for styling
'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css',
# Your custom JS logic
'restaurant_reservation/static/src/js/reservation_form.js',
],
},
Step 2: Create the Template
We'll create a structured XML template for our form. Notice the use of <optgroup> to categorize dietary options logically. This structure is automatically respected by Select2.
Select up to 3 preferences.
Step 3: Initialize with JavaScript
We use the public_widget registry to attach our logic. We'll use loadJS to ensure the library is loaded before we try to initialize it. We'll also configure Selection Limits and Placeholders.
/** @odoo-module **/
import publicWidget from "@web/legacy/js/public/public_widget";
import { loadJS } from "@web/core/assets";
publicWidget.registry.DietarySelect2 = publicWidget.Widget.extend({
selector: '.s_reservation_form', // Scope to our snippet container
start: function () {
this._super.apply(this, arguments);
// Dynamically load the JS library
loadJS("https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js")
.then(() => {
this._initializeSelect2();
})
.catch((err) => {
console.error("Failed to load Select2:", err);
});
},
_initializeSelect2: function () {
const $select = this.$('.s_select2_dietary');
$select.select2({
placeholder: "Select your dietary requirements...",
allowClear: true,
maximumSelectionLength: 3, // Enforce limit
width: '100%',
// Advanced: Custom no-results message
language: {
noResults: function () {
return "No matching diet found.";
}
}
});
// Optional: Listen for events
$select.on('select2:select', function (e) {
console.log('User selected:', e.params.data.text);
});
}
});
Conclusion
By wrapping standard form elements with Select2 in Odoo 18, you provide a sophisticated interface that handles complex data gracefully. Whether it's grouping allergens or limiting selections for a curated menu, these small UX improvements make a significant difference in perceived application quality.
Building a Customer Portal?
Don't settle for basic forms. Our team constructs high-performance Odoo portals with React–like reactivity and premium UX.
About the author
Head of Odoo Practice
Leads Braincuber's Odoo implementations across the US, India, and EU. Shipped 50+ Odoo deployments. Specializes in NetSuite and SAP Business One migrations.
