This guide demonstrates how to automatically expand all grouped records (multi-level) in a ListView in Odoo using a custom controller.
Purpose
By default, Odoo collapses grouped rows in a ListView. In cases where nested groups are used (e.g., multiple group_by
fields), you may want all groups to be automatically expanded when the view is loaded.
Implementation Overview
We override the default ListView's controller and implement logic to recursively expand each level of groupings using the model data structure.
📁 File Structure
You will define a new view type and controller in JavaScript:
expand_groups_list.js
/** @odoo-module **/
import {ListRenderer} from "@web/views/list/list_renderer";
import {ListController} from "@web/views/list/list_controller";
import {listView} from "@web/views/list/list_view";
import {registry} from "@web/core/registry";
import {onMounted} from "@odoo/owl";
/**
* Flatten nested arrays into a single array
*/
function flatten(arr) {
return arr.reduce((flat, toFlatten) => {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
/**
* Custom controller that expands all nested groups
*/
export class ExpandGroupsListController extends ListController {
setup() {
super.setup();
onMounted(() => {
this.expandAllGroups();
});
}
//ref: https://github.com/OCA/web/blob/17.0/web_group_expand/static/src/js/list_controller.esm.js
async expandAllGroups() {
let layer = this.model.root.groups;
while (layer.length) {
const closed = layer.filter(group => group._config.isFolded);
if (closed.length) {
closed.forEach(group => {
group._config.isFolded = false;
});
break;
}
layer = flatten(layer.map(group => group.list.groups || []));
}
await this.model.root.load();
this.model.notify();
}
}
export const ExpandGroupsListView = {
...listView,
Renderer: ListRenderer,
Controller: ExpandGroupsListController,
};
registry.category('views').add('expand_groups_custom', ExpandGroupsListView);
XML View Definition
using js_class
in xml view
<record id="mt_inspection_tree" model="ir.ui.view">
<field name="name">mt_inspection_inspection_tree</field>
<field name="model">mt.inspection</field>
<field name="arch" type="xml">
<tree
editable="bottom" expand="1"
js_class="expand_groups_custom" >
<field name="modify" readonly="1" width="10px"/>
<field name="material_need_date" readonly="1"/>
...
</tree>
</field>
</record>
All groups will seamlessly expand as soon as the view is opened
Reply