▶️ Introduction
A global search feature dramatically improves usability in Odoo — especially when users need to find records across many different apps without switching menus. In this tutorial, we’ll show you how to implement a smart global search system in Odoo 19, enabling users to perform quick searches across models like Contacts, Products, Sales Orders, Invoices, and more — all from a single search input. YouTube
This article expands on the concepts covered in the Odooistic video tutorial. Whether you’re building customer portals, dashboards, or advanced navigation systems, adding a smart search can elevate the user experience of your Odoo instance.
🎥 Video Tutorial:
📌 What You’ll Learn
By the end of this blog, you will know how to:
✔ Add a search input box accessible on main layouts
✔ Build a backend search controller to handle queries
✔ Create an API that searches across multiple models
✔ Display consolidated results grouped by model
🛠 Step-by-Step Implementation
Here’s how to implement a global smart search in your Odoo 19 project:
🔹 1. Create the Search Input UI
Add a search input box to your main view (e.g., in the navbar or header). This will be the entry point for user queries.
Example (XML snippet):
<header> <input type="search" name="global_search" placeholder="Search all records..." id="global_search_input"/> <button type="button" id="global_search_button">Search</button> </header>
This UI lets users enter a search term and trigger the search.
🔹 2. Frontend Logic (JavaScript)
Use JavaScript to capture the input value and send it to a backend controller via AJAX:
document.getElementById('global_search_button').addEventListener('click', () => { const query = document.getElementById('global_search_input').value; if (query) { fetch(`/global_search?q=${encodeURIComponent(query)}`) .then(response => response.json()) .then(data => { // render results dynamically }); } });
This code sends the user’s search query to the server and receives matched results in JSON format.
🔹 3. Backend Controller (Python)
Create a controller in your custom module to receive the search query and perform lookups across models:
from odoo import http from odoo.http import request class GlobalSearchController(http.Controller): @http.route('/global_search', type='json', auth='user') def global_search(self, q): models_to_search = [ ('res.partner', 'name'), ('product.product', 'name'), ('sale.order', 'name'), ('account.move', 'name'), ] results = {} for model, field in models_to_search: domain = [(field, 'ilike', q)] records = request.env[model].sudo().search_read(domain, ['id', field], limit=10) if records: results[model] = records return results
This controller:
Accepts the search term (q)
Searches across specified models using an ilike domain
Returns a JSON structure of matching records grouped by model
🔹 4. Render Results
Once the JSON is returned, the front end can dynamically display the results in a dropdown, modal, or a dedicated results page. For example, group items under headings like:
Contacts
Products
Sales Orders
Invoices
Each section shows matching records with clickable links.
🔎 Result Behavior
This search:
Performs case-insensitive matching
Searches key fields like name
Limits results to improve performance
Groups results by model
Returns a clean JSON response
You can extend the logic to include fields like email, reference codes, or even compute relevance ranking.
🧠 Tips & Best Practices
✔ Limit searches per model to avoid long response times.
✔ Consider adding full-text search indexes if performance becomes a concern.
✔ Extend search to include related fields (e.g., product category or partner email).
✔ Add loader animations to improve UX for long queries.