Angular DataGrid - Master-Detail Interface
User Interaction
The master-detail interface supplies a standard data row with an expandable section that contains detail data. In master-detail terms, the data row is called "master row" and the expandable section - "detail section".

The master-detail interface becomes available after you specify the detail sections' contents using the masterDetail.template property. You can expand and collapse detail sections programmatically or enable a user to do it by setting the masterDetail.enabled property to true. Set the masterDetail.autoExpandAll property to true to expand these sections by default.
jQuery
$(function() {
$("#dataGridContainer").dxDataGrid({
// ...
masterDetail: {
enabled: true,
autoExpandAll: true,
template: function (container, info) {
сonst currentEmployeeData = info.data;
container.append(
$(`<div class="employeeInfo">
<img class="employeePhoto" src=${currentEmployeeData.Picture}/>
<p class="employeeNotes">${currentEmployeeData.Notes}</p>
</div>`)
);
}
}
});
});Angular
<dx-data-grid ... >
<dxo-master-detail
[enabled]="true"
[autoExpandAll]="true"
[template]="'detail'">
</dxo-master-detail>
<div *dxTemplate="let employee of 'detail'">
<div class="employeeInfo">
<img class="employeePhoto" [src]="employee.data.Picture" />
<p class="employeeNotes">{{employee.data.Notes}}</p>
</div>
</div>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
// ...
}
@NgModule({
imports: [
// ...
DxDataGridModule
],
// ...
})Vue
<template>
<DxDataGrid ... >
<DxMasterDetail
:enabled="true"
:auto-expand-all="true"
template="detail"
/>
<template #detail="{ data }">
<div class="employeeInfo">
<img class="employeePhoto" :src="data.Picture" />
<p class="employeeNotes">{{ data.Notes }}</p>
</div>
</template>
</DxDataGrid>
</template>
<script>
import 'devextreme/dist/css/dx.light.css';
import DxDataGrid, {
DxMasterDetail
} from 'devextreme-vue/data-grid';
export default {
components: {
DxDataGrid,
DxMasterDetail
},
// ...
}
</script>React
import React from 'react';
import 'devextreme/dist/css/dx.light.css';
import DataGrid, {
MasterDetail
} from 'devextreme-react/data-grid';
const DetailSection = ({ data }) => {
return (
<div class="employeeInfo">
<img class="employeePhoto" src={data.Picture} />
<p class="employeeNotes">{data.Notes}</p>
</div>
);
};
export default function App() {
return (
<DataGrid ... >
<MasterDetail
enabled={true}
autoExpandAll={true}
render={DetailSection}
/>
</DataGrid>
);
}Once loaded, a detail section's content remains cached until a user switches to another page in the DataGrid or reloads the web page.
API
Pass -1 to the expandAll(groupIndex) or collapseAll(groupIndex) method to expand or collapse all master rows at once.
jQuery
const dataGrid = $("#dataGridContainer").dxDataGrid("instance");
dataGrid.expandAll(-1);
dataGrid.collapseAll(-1);Angular
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {
@ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
// Prior to Angular 8
// @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
expandAllMasterRows () {
this.dataGrid.instance.expandAll(-1);
}
collapseAllMasterRows () {
this.dataGrid.instance.collapseAll(-1);
}
}
@NgModule({
imports: [
// ...
DxDataGridModule
],
// ...
})Vue
<template>
<DxDataGrid ...
:ref="dataGridRefKey">
<!-- ... -->
</DxDataGrid>
</template>
<script>
import 'devextreme/dist/css/dx.light.css';
import DxDataGrid, { ... } from 'devextreme-vue/data-grid';
const dataGridRefKey = "my-data-grid";
export default {
components: {
DxDataGrid,
// ...
},
data: function() {
return {
dataGridRefKey
};
},
methods: {
expandAllMasterRows() {
this.dataGrid.expandAll(-1);
},
collapseAllMasterRows() {
this.dataGrid.collapseAll(-1);
}
},
computed: {
dataGrid: function() {
return this.$refs[dataGridRefKey].instance;
}
}
}
</script>React
import React, { useRef, useCallback } from 'react';
import 'devextreme/dist/css/dx.light.css';
import DataGrid, { ... } from 'devextreme-react/data-grid';
export default function App() {
const dataGrid = useRef(null);
const expandAllMasterRows = useCallback(() => {
dataGrid.current.instance().expandAll(-1);
}, []);
const collapseAllMasterRows = useCallback(() => {
dataGrid.current.instance().collapseAll(-1);
}, []);
return (
<DataGrid ...
ref={dataGrid}>
{/* ... */}
</DataGrid>
);
}The expandRow(key) and collapseRow(key) methods expand and collapse an individual master row. You can check a row's current state by calling the isRowExpanded(key) method.
jQuery
function toggleMasterRow (rowKey) {
const dataGrid = $("#dataGridContainer").dxDataGrid("instance");
if (dataGrid.isRowExpanded(rowKey)) {
dataGrid.collapseRow(rowKey);
} else {
dataGrid.expandRow(rowKey);
}
}Angular
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {
@ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
// Prior to Angular 8
// @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
toggleMasterRow (rowKey) {
if (this.dataGrid.instance.isRowExpanded(rowKey)) {
this.dataGrid.instance.collapseRow(rowKey);
} else {
this.dataGrid.instance.expandRow(rowKey);
}
}
}
@NgModule({
imports: [
// ...
DxDataGridModule
],
// ...
})Vue
<template>
<DxDataGrid ...
:ref="dataGridRefKey">
<!-- ... -->
</DxDataGrid>
</template>
<script>
import 'devextreme/dist/css/dx.light.css';
import DxDataGrid, { ... } from 'devextreme-vue/data-grid';
const dataGridRefKey = "my-data-grid";
export default {
components: {
DxDataGrid,
// ...
},
data: function() {
return {
dataGridRefKey
};
},
methods: {
toggleMasterRow(rowKey) {
if (this.dataGrid.isRowExpanded(rowKey)) {
this.dataGrid.collapseRow(rowKey);
} else {
this.dataGrid.expandRow(rowKey);
}
}
},
computed: {
dataGrid: function() {
return this.$refs[dataGridRefKey].instance;
}
}
}
</script>React
import React, { useRef, useCallback } from 'react';
import 'devextreme/dist/css/dx.light.css';
import DataGrid, { ... } from 'devextreme-react/data-grid';
export default function App() {
const dataGrid = useRef(null);
const toggleMasterRow = useCallback((rowKey) => {
if (dataGrid.current.instance().isRowExpanded(rowKey)) {
dataGrid.current.instance().collapseRow(rowKey);
} else {
dataGrid.current.instance().expandRow(rowKey);
}
}, []);
return (
<DataGrid ...
ref={dataGrid}>
{/* ... */}
</DataGrid>
);
}Events
Events raised for a master row when a user expands or collapses it are identical to the events raised for expanding or collapsing a group. See this topic for details.
If you have technical questions, please create a support ticket in the DevExpress Support Center.