DevExtreme v26.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Vue Data Grid - Master-Detail View

The Master-Detail View allows users to expand a row ('master') and display the related content ('details') in the expanded section. To configure this feature, set the the masterDetail object's enabled property to true and use a template to specify detail section content. In this demo, the detail section displays another DataGrid.

Backend API
<template> <DxDataGrid id="grid-container" :show-borders="true" :data-source="employees" key-expr="ID" > <DxColumn :width="70" data-field="Prefix" caption="Title" /> <DxColumn data-field="FirstName"/> <DxColumn data-field="LastName"/> <DxColumn :width="170" data-field="Position" /> <DxColumn :width="125" data-field="State" /> <DxColumn data-field="BirthDate" data-type="date" /> <DxMasterDetail :enabled="true" template="masterDetailTemplate" /> <template #masterDetailTemplate="{ data: employee }"> <DetailTemplate :template-data="employee" /> </template> </DxDataGrid> </template> <script setup lang="ts"> import { DxDataGrid, DxColumn, DxMasterDetail, } from 'devextreme-vue/data-grid'; import DetailTemplate from './DetailTemplate.vue'; import { employees } from './data.ts'; </script> <style> #grid-container { height: 440px; } </style>
<template> <div> <div class="master-detail-caption">{{ detailInfo }}</div> <DxDataGrid :data-source="dataSource" :show-borders="true" :column-auto-width="true" > <DxColumn data-field="Subject"/> <DxColumn data-field="StartDate" data-type="date" /> <DxColumn data-field="DueDate" data-type="date" /> <DxColumn data-field="Priority"/> <DxColumn :calculate-cell-value="completedValue" data-type="boolean" caption="Completed" /> </DxDataGrid> </div> </template> <script setup lang="ts"> import { reactive } from 'vue'; import { DxDataGrid, DxColumn, type DxDataGridTypes } from 'devextreme-vue/data-grid'; import { ArrayStore, DataSource } from 'devextreme-vue/common/data'; import { tasks, type Task } from './data.ts'; const props = defineProps<{ templateData: DxDataGridTypes.MasterDetailTemplateData }>(); const dataSource = getTasks(props.templateData.key); const itemData = reactive(props.templateData.data); const detailInfo = `${itemData.FirstName} ${itemData.LastName}'s Tasks:`; const completedValue = (rowData: Task) => rowData.Status === 'Completed'; function getTasks(key: number) { return new DataSource({ store: new ArrayStore({ data: tasks, key: 'ID', }), filter: ['EmployeeID', '=', key], }); } </script> <style> .master-detail-caption { padding: 0 0 5px 10px; font-size: 14px; font-weight: bold; } </style>
export type Task = { ID: number; Subject: string; StartDate: string; DueDate: string; Status: string; Priority: string; Completion: number; EmployeeID: number; }; export type Employee = { ID: number; FirstName: string; LastName: string; Prefix: string; Position: string; BirthDate: string; State: string; }; export const employees: Employee[] = [{ ID: 1, Prefix: 'Mr.', FirstName: 'John', LastName: 'Heart', Position: 'CEO', State: 'California', BirthDate: '1964/03/16', }, { ID: 2, Prefix: 'Mrs.', FirstName: 'Olivia', LastName: 'Peyton', Position: 'Sales Assistant', State: 'California', BirthDate: '1981/06/03', }, { ID: 3, Prefix: 'Mr.', FirstName: 'Robert', LastName: 'Reagan', Position: 'CMO', State: 'Arkansas', BirthDate: '1974/09/07', }, { ID: 4, Prefix: 'Ms.', FirstName: 'Greta', LastName: 'Sims', Position: 'HR Manager', State: 'Georgia', BirthDate: '1977/11/22', }, { ID: 5, Prefix: 'Mr.', FirstName: 'Brett', LastName: 'Wade', Position: 'IT Manager', State: 'Idaho', BirthDate: '1968/12/01', }, { ID: 6, Prefix: 'Mrs.', FirstName: 'Sandra', LastName: 'Johnson', Position: 'Controller', State: 'Utah', BirthDate: '1974/11/15', }, { ID: 7, Prefix: 'Mr.', FirstName: 'Kevin', LastName: 'Carter', Position: 'Shipping Manager', State: 'California', BirthDate: '1978/01/09', }, { ID: 8, Prefix: 'Ms.', FirstName: 'Cynthia', LastName: 'Stanwick', Position: 'HR Assistant', State: 'Arkansas', BirthDate: '1985/06/05', }, { ID: 9, Prefix: 'Dr.', FirstName: 'Kent', LastName: 'Samuelson', Position: 'Ombudsman', State: 'Missouri', BirthDate: '1972/09/11', }]; export const tasks: Task[] = [{ ID: 1, Subject: 'Prepare 2023 Financial', StartDate: '2023/01/15', DueDate: '2023/01/31', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 8, }, { ID: 2, Subject: 'Prepare 2023 Marketing Plan', StartDate: '2023/01/01', DueDate: '2023/01/31', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 5, }, { ID: 3, Subject: 'Update Personnel Files', StartDate: '2023/02/03', DueDate: '2023/02/28', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 2, }, { ID: 4, Subject: 'Review Health Insurance Options Under the Affordable Care Act', StartDate: '2023/02/12', DueDate: '2023/04/25', Status: 'In Progress', Priority: 'High', Completion: 50, EmployeeID: 2, }, { ID: 5, Subject: 'Choose between PPO and HMO Health Plan', StartDate: '2023/02/15', DueDate: '2023/04/15', Status: 'In Progress', Priority: 'High', Completion: 75, EmployeeID: 1, }, { ID: 6, Subject: 'Google AdWords Strategy', StartDate: '2023/02/16', DueDate: '2023/02/28', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 1, }, { ID: 7, Subject: 'New Brochures', StartDate: '2023/02/17', DueDate: '2023/02/24', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 1, }, { ID: 11, Subject: 'Rollout of New Website and Marketing Brochures', StartDate: '2023/02/20', DueDate: '2023/02/28', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 5, }, { ID: 12, Subject: 'Update Sales Strategy Documents', StartDate: '2023/02/20', DueDate: '2023/02/22', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 9, }, { ID: 15, Subject: 'Review 2022 Sales Report and Approve 2023 Plans', StartDate: '2023/02/23', DueDate: '2023/02/28', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 5, }, { ID: 16, Subject: 'Deliver R&D Plans for 2023', StartDate: '2023/03/01', DueDate: '2023/03/10', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 3, }, { ID: 20, Subject: 'Approve Hiring of John Jeffers', StartDate: '2023/03/02', DueDate: '2023/03/12', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 4, }, { ID: 20, Subject: 'Approve Hiring of John Jeffers', StartDate: '2023/03/02', DueDate: '2023/03/12', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 6, }, { ID: 21, Subject: 'Non-Compete Agreements', StartDate: '2023/03/12', DueDate: '2023/03/14', Status: 'Completed', Priority: 'Low', Completion: 100, EmployeeID: 2, }, { ID: 22, Subject: 'Update NDA Agreement', StartDate: '2023/03/14', DueDate: '2023/03/16', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 1, }, { ID: 23, Subject: 'Update Employee Files with New NDA', StartDate: '2023/03/16', DueDate: '2023/03/26', Status: 'Need Assistance', Priority: 'Normal', Completion: 90, EmployeeID: 4, }, { ID: 24, Subject: 'Update Employee Files with New NDA', StartDate: '2023/03/16', DueDate: '2023/03/26', Status: 'Need Assistance', Priority: 'Normal', Completion: 90, EmployeeID: 6, }, { ID: 25, Subject: 'Sign Updated NDA', StartDate: '2023/03/20', DueDate: '2023/03/25', Status: 'Completed', Priority: 'Urgent', Completion: 100, EmployeeID: 7, }, { ID: 26, Subject: 'Sign Updated NDA', StartDate: '2023/03/20', DueDate: '2023/03/25', Status: 'Completed', Priority: 'Urgent', Completion: 100, EmployeeID: 8, }, { ID: 27, Subject: 'Sign Updated NDA', StartDate: '2023/03/20', DueDate: '2023/03/25', Status: 'Need Assistance', Priority: 'Urgent', Completion: 25, EmployeeID: 9, }, { ID: 35, Subject: 'Update Revenue Projections', StartDate: '2023/03/24', DueDate: '2023/04/07', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 8, }, { ID: 36, Subject: 'Review Revenue Projections', StartDate: '2023/03/25', DueDate: '2023/04/06', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 9, }, { ID: 40, Subject: 'Provide New Health Insurance Docs', StartDate: '2023/03/28', DueDate: '2023/04/07', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 4, }, { ID: 41, Subject: 'Provide New Health Insurance Docs', StartDate: '2023/03/28', DueDate: '2023/04/07', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 6, }, { ID: 50, Subject: 'Give Final Approval for Refunds', StartDate: '2023/05/05', DueDate: '2023/05/15', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 2, }, { ID: 52, Subject: 'Review Product Recall Report by Engineering Team', StartDate: '2023/05/17', DueDate: '2023/05/20', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 1, }, { ID: 55, Subject: 'Review Overtime Report', StartDate: '2023/06/10', DueDate: '2023/06/14', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 7, }, { ID: 60, Subject: 'Refund Request Template', StartDate: '2023/06/17', DueDate: '2024/04/01', Status: 'Deferred', Priority: 'Normal', Completion: 0, EmployeeID: 9, }, { ID: 71, Subject: 'Upgrade Server Hardware', StartDate: '2023/07/22', DueDate: '2023/07/31', Status: 'Completed', Priority: 'Urgent', Completion: 100, EmployeeID: 7, }, { ID: 72, Subject: 'Upgrade Personal Computers', StartDate: '2023/07/24', DueDate: '2024/04/30', Status: 'In Progress', Priority: 'Normal', Completion: 85, EmployeeID: 7, }, { ID: 74, Subject: 'Decide on Mobile Devices to Use in the Field', StartDate: '2023/07/30', DueDate: '2023/08/02', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 3, }, { ID: 78, Subject: 'Try New Touch-Enabled WinForms Apps', StartDate: '2023/08/11', DueDate: '2023/08/15', Status: 'Completed', Priority: 'Normal', Completion: 100, EmployeeID: 3, }, { ID: 81, Subject: 'Review Site Up-Time Report', StartDate: '2023/08/24', DueDate: '2023/08/30', Status: 'Completed', Priority: 'Urgent', Completion: 100, EmployeeID: 5, }, { ID: 99, Subject: 'Submit D&B Number to ISP for Credit Approval', StartDate: '2023/11/04', DueDate: '2023/11/07', Status: 'Completed', Priority: 'High', Completion: 100, EmployeeID: 8, }, { ID: 117, Subject: 'Approval on Converting to New HDMI Specification', StartDate: '2024/01/11', DueDate: '2024/01/31', Status: 'Deferred', Priority: 'Normal', Completion: 75, EmployeeID: 3, }, { ID: 138, Subject: 'Review HR Budget Company Wide', StartDate: '2024/03/20', DueDate: '2024/03/25', Status: 'In Progress', Priority: 'Normal', Completion: 40, EmployeeID: 6, }, { ID: 145, Subject: 'Final Budget Review', StartDate: '2024/03/26', DueDate: '2024/03/27', Status: 'In Progress', Priority: 'High', Completion: 25, EmployeeID: 6, }];
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="./bundle.css" /> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> <script src="bundles/vendor/vue.vendor.js"></script> <script src="./bundle.js"></script> </body> </html>