| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 294 |
| Technical Name |
list_merge_header |
| License | AGPL-3 |
| Website | http://nguyentuann1004@gmail.com |
List View Merge Header
Add Excel-like merged column headers to any Odoo 19 list/tree view.
Group related columns under a shared label using a simple <merge> XML tag β
no JavaScript configuration, no Python hacks, just clean XML.
Key Features
Everything you need to display professional merged column headers in Odoo list views, out of the box.
|
π·οΈ
<merge> XML TagWrap any group of <field> tags inside a <merge string="Label"> node. That is all β the module does the rest automatically. |
π
Two-Row Header LayoutAutomatically renders a two-row <thead>: Row 1 shows the group label spanning all merged columns, Row 2 shows individual field headers β identical to Excel merged cells. |
β‘
OWL Patch β Zero OverheadUses Odoo 19's OWL patch() API to extend ListArchParser and ListRenderer. Views without <merge> tags render the original single-row header unchanged. |
|
π
Mixed Columns SupportMix merged and non-merged columns freely in the same list view. Non-merged columns automatically get rowspan="2" so they align perfectly with the two-row layout. |
β
RNG Validation PatchedPatches Odoo's internal RNG schema validator so <merge> tags are accepted without any validation error on module install or view save. |
π
Sort & Resize PreservedColumn sorting, column resizing, optional columns dropdown, and record selector checkbox all continue to work exactly as in the stock Odoo list view β no regressions. |
See It In Action
Real screenshot from a live Odoo 19 instance.
Merged Headers In a List View
Columns are grouped under a shared merge label in the first header row. Non-merged columns span both rows automatically with rowspan="2". Individual field headers with full sort functionality appear in the second row.
How to Use It
Simply wrap the columns you want to group inside a <merge string="Your Label"> tag in your list/tree view XML:
<list string="My Records">
<field name="name"/>
<field name="user_id"/>
<!-- Group date columns under a shared label -->
<merge string="Dates">
<field name="date_start"/>
<field name="date_deadline"/>
<field name="date_end"/>
</merge>
<!-- Another merge group -->
<merge string="Financials">
<field name="amount_untaxed"/>
<field name="amount_tax"/>
<field name="amount_total"/>
</merge>
<field name="state"/>
</list>
The string attribute on <merge> is the label shown in the first header row. You can have multiple <merge> groups in the same list view. Views without any <merge> tags behave exactly as before β no performance impact.
Technical Architecture
Clean, minimal implementation following Odoo 19 best practices.
|
π§©
ListArchParser PatchPre-scans the XML arch for <merge> nodes to build a mergeInfo map (fieldName to groupId + label). After the original parser runs, each column object is annotated with its mergeGroup metadata. |
πΌοΈ
ListRenderer PatchAdds hasMergeHeaders, getMergeGroups(), and mergeSubColumns getters consumed by the OWL template to build the two-row <thead>. Adjacent columns with the same groupId are collapsed into a single colspan cell. |
|
π
OWL Template ExtensionInherits and replaces the <thead> of web.ListRenderer using t-inherit-mode="extension". When no merge groups exist, it falls back to the original single-row rendering β no visual change for standard views. |
π‘οΈ
Python RNG Validator PatchExtends ir.ui.view to register a _validate_tag_merge handler and patches Odoo's internal schema_valid validator to unwrap <merge> nodes before validation β ensuring clean installs with no schema errors. |
List View Merge Header vs Standard Odoo List
| Feature | With This Module | Stock Odoo 19 |
|---|---|---|
| Merged column group headers (Excel-style) | β | β |
| Pure XML configuration β no custom Python or JS per view | β | β |
| Multiple merge groups in the same view | β | β |
| Mix merged and non-merged columns freely | β | β |
| Column sorting preserved in merged columns | β | β |
| Optional columns dropdown preserved | β | β |
| RNG schema validation compatible (no install error) | β | β |
Frequently Asked Questions
| Does this affect views that do not use <merge>? No. The OWL template checks hasMergeHeaders before rendering the two-row layout. If the view has no <merge> tags, the original single-row header is rendered exactly as in stock Odoo β zero overhead. |
| Can I have more than one <merge> group in the same list view? Yes. Each <merge> node gets its own unique group ID. You can place multiple merge groups anywhere in the column list and freely mix them with regular non-merged columns. |
| Will Odoo throw a validation error when I save a view with <merge>? No. The module patches both Odoo's RNG schema validator (Python-side) and registers a _validate_tag_merge handler on ir.ui.view. The <merge> tag is fully accepted without any error during module installation or view editing. |
| Does column sorting still work inside a merged group? Yes. Each individual field header in the second row retains full click-to-sort behaviour. The sort arrow and column resize handle are rendered on the second-row <th> elements, exactly as they would be in a regular single-row header. |
| Does it require any Python dependencies? No external packages needed. The module depends only on the built-in web module and uses lxml (already part of Odoo's standard environment) for the RNG validator patch. |
Need Help?
Full support included. Bug reports, feature requests, or custom integration questions β just reach out!
nguyentuann1004@gmail.comVersion: 19.0.1.0.0 | License: LGPL-3 | Author: Tuan Nguyen Van
Compatible with Odoo 19 Community, Enterprise, and Odoo.sh
Β© 2026 Tuan Nguyen Van. All rights reserved.
Please log in to comment on this module
Amazing module!
Thank you for sharing such a high-quality module. I'm very impressed and will definitely check out your other modules. Looking forward to seeing more great work from you. Keep it up!
Amazing module!
Thank you for sharing such a high-quality module. I'm very impressed and will definitely check out your other modules. Looking forward to seeing more great work from you. Keep it up!
Amazing module!
Hi John,
Thank you so much for the 5-star review β it really means a lot to me. Feedback like yours is a huge motivation to keep building and sharing more modules with the Odoo community.
I'm glad the merged header feature worked smoothly for your project and saved you some customization time. That was exactly the goal.
If you have a moment, feel free to check out my other modules on Odoo Apps β there are quite a few you might find useful, such asΒ Search One2many,Β Quick Edit Excel, and several others built with the same focus on practical, real-world use cases.
Thanks again for your support. Wishing you success with your Odoo projects!
Best regards,
Tuan Nguyen Van