Advanced Master-Detail View - DevExtreme Data Grid: Vue Components by DevExpress DevExtreme by DevExpress Overview What's New Roadmap Demos Docs Support Theme Builder Blogs Free Trial Buy Data Grid Overview Data Binding Simple Array JSON Data OData Service Custom Data Source Web API Service SignalR Service Real-Time Updates Paging and Scrolling Record Paging Local Virtual Scrolling Remote Virtual Scrolling Horizontal Virtual Scrolling Infinite Scrolling Editing Row Editing and Editing Events Cell Editing and Editing API Batch Editing Form Editing Popup Editing Custom Editors Data Validation Cascading Lookups Collaborative Editing CRUD Operations Customize Keyboard Navigation Batch Update Request Edit State Management Custom New Record Position Grouping Record Grouping Remote Grouping Filtering and Sorting Multiple Sorting Filtering Filtering API Filter Panel Focused Row Row Drag & Drop Local Reordering Remote Reordering Drag & Drop Between Two Grids Selection Row Selection Multiple Record Selection Multiple Record Selection API Deferred Selection Columns Column Customization Columns based on a Data Source Multi-Level Headers (Bands) Column Resizing Command Column Customization State Persistence Appearance Appearance Right-To-Left Support Templates Column Template Row Template Cell Customization Toolbar Customization Data Summaries Total Summaries Group Summaries Custom Summaries Recalculate While Editing Master-Detail Master-Detail View Master-Detail API Advanced Master-Detail View Export to PDF Overview Cell Customization Header and Footer Export Multiple Grids Export Images Export to Excel Overview Cell Customization Header and Footer Export Multiple Grids Export Images Adaptability Grid Adaptability Overview Grid Columns Hiding Priority Keyboard Navigation Pivot Grid Overview Data Binding Simple Array OLAP Data Source Web API Service Field Chooser Integrated Field Chooser Standalone Field Chooser Features Field Panel Header Filter Running Totals Summary Display Modes Drill Down Virtual Scrolling Remote Virtual Scrolling State Persistence Chart Integration Layout Customization Export to Excel Overview Cell Customization Header and Footer Tree List Overview Data Binding Simple Array: Plain Structure Simple Array: Hierarchical Structure Load Data on Demand Web API Service Sorting Paging Editing Row Editing Cell Editing Batch Editing Form Editing Popup Editing Customize Keyboard Navigation Node Drag & Drop Focused Row Selection Single Row Selection Multiple Row Selection Filtering Using Search Panel Using Filter Row Using Header Filter Filter Panel Filter Modes Column Customization Column Chooser Column Reordering Column Resizing Column Fixing State Persistence Adaptability Keyboard Navigation Scheduler Overview Data Binding Simple Array Web API Service SignalR Service Google Calendar Integration Views Basic Views Timelines Agenda Features Current Time Indicator Time Zone Support Recurring Appointments Editing Custom Drag & Drop Resources All Day Panel Mode Virtual Scrolling Grouping Group Orientation Grouping By Date Customization Custom Templates Disabled Date/Time Ranges Customize Individual Views Increased View Duration Limit the Appointment Count per Cell Context Menu Integration Adaptability Html Editor Overview Output Formats Toolbar Customization Mentions Tables Diagram Overview Data Binding Node and Edge Arrays Node List: Linear Array Node List: Hierarchical Array Advanced Data Binding Web API Service Featured Shapes Containers OrgChart Shapes Custom Shapes Background Images Shapes with Base Type Templates Templates with Editing Document Capabilities Read Only Mode Simple View User Interaction Item Selection Editing Restrictions UI Customization Adaptability Charts Overview Data Binding Simple Array JSON Data Client-Side Data Processing Server-Side Data Processing Dynamic Series from the DataSource SignalR Service Load Data On Demand Area Charts Area Spline Area Step Area Step Area with Gaps Bar Charts Standard Bar Side-by-Side Bar Stacked Bar Full Stacked Bar Side-by-Side Stacked Bar Drill-Down Chart Side-by-Side Full-Stacked Bar Auto-Calculated Bar Width Custom Bar Width Color Each Bar Differently Customize Points and Labels Scale Breaks Bi-Directional Bar Chart Custom Annotations Bullet Charts Doughnut Charts Doughnut Doughnut Selection Doughnut with Top N Series Doughnut with Multiple Series Custom Label in the Center Financial Charts Stock Candlestick Points Aggregation Chart with Annotations Line Charts Line Spline Resolved Axis Label Overlapping Hover Mode Step Line Crosshair Point Image Logarithmic vs Linear Axes Pie Charts Pie Pies with Equal Sizes Pie with Custom Labels Pie with Small Values Grouped Pie with Resolved Label Overlapping Palette Pie with Annotations Point Charts Scatter Bubble Scatter Logarithmic Axis Custom Axis Position Polar and Radar Charts Continuous Data Discrete Data Spider Web Wind Rose Periodic Data Inverted Chart Polar Chart with Annotations Range Charts Range Bar Timeline Chart Range Area Sparkline Charts Sparklines Area Sparklines Bar Sparklines Winloss Sparklines Tree Map Hierarchical Data Structure Plain Data Structure Tiling Algorithms Colorization Drill Down Funnel and Pyramid Charts Funnel Chart Pyramid Chart Sankey Chart Combinations Multiple Axes Multiple Panes Points Aggregation Error Bars Pareto Chart Custom Legend Markers Discrete Aggregation Axis Label Templates Strips More Features Export Export and Printing API Export Several Charts Export Custom Markup Selection Selection Multiple Series Selection Multiple Point Selection API - Select a Point Tooltips API - Display a Tooltip Tooltips: HTML Markup Support Zooming Zooming on Area Selection Zooming and Panning Zooming and Panning API Discrete Axis Zooming and Panning Polar Chart Zooming and Panning API Gantt Overview Data Data Binding and Editing Validation UI Customization Chart Appearance Task Template Toolbar Context Menu Strip Lines Export to PDF Sorting Filtering Filter Row Header Filter Gauges Overview Data Binding Update Circular Gauge Data at Runtime Update Linear Gauge Data at Runtime Update Bar Gauge Data at Runtime Bar Gauge Labels Customization Palette Tooltip and Legend Variable Number of Bars Circular Gauge Palette for Ranges Scale Minor Ticks Scale Label Formatting Different Value Indicator Types Different Subvalue Indicator Types Subvalue Indicator Text Formatting Custom Layout Angles Customization Gauge Title Customized Gauge Tooltip Value Indicators API Linear Gauge Scale Custom Tick Interval Scale Custom Tick Values Different Value Indicator Types Different Subvalue Indicator Types Base Value for Range Bar Custom Layout Variable Number of Subvalue Indicators Navigation Overview Accordion Menu Multi View Drawer Left or Right Position Top or Bottom Position Tab Panel Overview Tab Drag & Drop Tabs Toolbar Tree View Hierarchical Data Structure Plain Data Structure Node Selection and Customization Virtual Mode Load Data on Demand TreeView with Search Bar ContextMenu Integration Drag & Drop and Reordering Drag & Drop for Plain Data Structure Drag & Drop for Hierarchical Data Structure Right-to-Left Support Editors Overview Autocomplete Calendar Check Box Color Box Date Box Overview Formatting Drop Down Box Single Selection Multiple Selection Number Box Overview Formatting Select Box Overview Search and Editing Customize Drop-Down Button Grouped Items Switch Tag Box Overview Grouped Items Tag Count Limitation Text Area Text Box Validation Custom Text Editor Buttons Right-to-Left Support Editor Appearance Variants Forms and Multi-Purpose Overview Box Button Group Field Set Filter Builder With Data Grid With List Customization Form Overview Customize Item Grouped Fields Columns Adaptability Validation Customize Fields at Runtime Radio Group Range Selector Numeric Scale (Lightweight) Numeric Scale Date-Time Scale (Lightweight) Date-Time Scale Logarithmic Scale Discrete scale Custom Formatting Use Range Selection for Calculation Use Range Selection for Filtering Image on Background Chart on Background Customized Chart on Background Chart on Background with Series Template Range Slider Responsive Box Scroll View Slider Sortable Kanban Customization File Management File Manager Overview File System Types Physical File System Entity Framework ORM Azure Server-Side Binding Azure Client-Side Binding Hierarchical JS Structure Customization Custom Thumbnails Toolbar and Context Menu File Uploader Form Upload Async Upload Validation Chunk Uploading Direct Upload to Azure Custom Drop Zone Actions and Lists Overview Action Sheet Basics Popover Mode Button Predefined Types Icons Floating Action Button Drop Down Button Context Menu Basics Templates Gallery Overview Item Template List Item Deletion UI Grouped List Item Template List with Search Bar List Selection Item Drag & Drop Web API Service Lookup Basics Templates Handle Value Change Tile View Basics Directions Item Template Resizable Maps Overview Map Providers and Types Markers Routes Vector Map Colors Customization Zooming and Centering Palette Image Markers Bubble Markers Pie Markers Dynamic Viewport Area with Labels and Two Legends Tooltips: HTML Markup Support Custom Projection Floor Plan Multiple Layers Custom Map Data Custom Annotations Dialogs and Notifications Overview Load Indicator Load Panel Popover Popup Overview Scrolling Progress Bar Toast Overview Stack Tooltip Localization Using Intl Using Globalize Related Demos: Your search did not match any results. Advanced Master-Detail View This demo illustrates an advanced master-detail view in the DataGrid component. Master rows represent suppliers. Detail sections contain TabPanel components with two tabs: Orders and Address. In the Orders tab, you can choose a supplier's product from the SelectBox, and the DataGrid under it will show orders placed on this product. The Address tab displays the supplier's address. See more Hide details Prev Demo Next Demo Was this demo helpful? Thank you! Feel free to share demo-related thoughts here. If you have technical questions, please create a support ticket in the DevExpress Support Center. x Send Feedback Thank you! We appreciate your feedback. jQuery Angular Vue React AngularJS ASP.NET Core ASP.NET MVC Backend API Copy to CodeSandBox Apply Reset <template> <DxDataGrid id="gridContainer" :data-source="suppliersData" :remote-operations="true" :show-borders="true" > <DxPaging :page-size="15"/> <DxColumn data-field="ContactName"/> <DxColumn data-field="ContactTitle"/> <DxColumn data-field="CompanyName"/> <DxColumn data-field="City"/> <DxColumn data-field="Country"/> <DxMasterDetail :enabled="true" template="master-detail" /> <template #master-detail="{ data }"> <MasterDetail :master-detail-data="data"/> </template> </DxDataGrid> </template> <script> import { DxDataGrid, DxColumn, DxPaging, DxMasterDetail, } from 'devextreme-vue/data-grid'; import { createStore } from 'devextreme-aspnet-data-nojquery'; import MasterDetail from './MasterDetail.vue'; const url = 'https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView'; export default { components: { DxDataGrid, DxColumn, DxPaging, DxMasterDetail, MasterDetail, }, data() { return { suppliersData: createStore({ key: 'SupplierID', loadUrl: `${url}/GetSuppliers`, }), }; }, }; </script> <template> <DxForm :form-data="data" :items="items" :col-count="2" :customize-item="customizeItem" class="address-form form-container" > <template #form-item="{ data: item }"> <span> {{ item.editorOptions.value }} </span> </template> </DxForm> </template> <script> import { DxForm } from 'devextreme-vue/form'; export default { components: { DxForm }, props: { data: { type: Object, default: () => ({}), }, }, data() { return { items: ['Address', 'City', 'Region', 'PostalCode', 'Country', 'Phone'], }; }, methods: { customizeItem(item) { item.template = 'form-item'; }, }, }; </script> <template> <DxTabPanel> <DxItem title="Orders" template="orders-tab" /> <template #orders-tab> <OrdersTab :supplier-id="masterDetailData.key" /> </template> <DxItem title="Address" template="address-tab" /> <template #address-tab> <AddressTab :data="masterDetailData.data" /> </template> </DxTabPanel> </template> <script> import { DxTabPanel, DxItem } from 'devextreme-vue/tab-panel'; import OrdersTab from './OrdersTab.vue'; import AddressTab from './AddressTab.vue'; export default { components: { DxTabPanel, DxItem, OrdersTab, AddressTab, }, props: { masterDetailData: { type: Object, default: () => ({}), }, }, }; </script> <template> <div> <DxDataGrid :data-source="orderHistoryStore" :show-borders="true" > <DxPaging :page-size="5"/> <DxColumn data-field="OrderID"/> <DxColumn data-field="OrderDate" data-type="date" /> <DxColumn data-field="ShipCountry"/> <DxColumn data-field="ShipCity"/> <DxColumn data-field="UnitPrice" format="currency" /> <DxColumn data-field="Quantity"/> <DxColumn data-field="Discount" format="percent" /> <DxSummary> <DxTotalItem column="UnitPrice" summary-type="sum" > <DxValueFormat :precision="2" format="currency" /> </DxTotalItem> <DxTotalItem column="Quantity" summary-type="count" /> </DxSummary> </DxDataGrid> </div> </template> <script> import { DxDataGrid, DxColumn, DxPaging, DxSummary, DxTotalItem, DxValueFormat, } from 'devextreme-vue/data-grid'; import { createStore } from 'devextreme-aspnet-data-nojquery'; const url = 'https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView'; export default { components: { DxDataGrid, DxColumn, DxPaging, DxSummary, DxTotalItem, DxValueFormat, }, props: { productId: { type: Number, default: null, }, }, computed: { orderHistoryStore() { return this.productId === null ? null : { store: createStore({ key: 'OrderID', loadParams: { ProductID: this.productId }, loadUrl: `${url}/GetOrdersByProduct`, }), }; }, }, }; </script> <template> <DxForm label-location="top" class="form-container" > <DxItem template="select-box"> <DxLabel text="Product"/> </DxItem> <template #select-box> <ProductSelectBox :supplier-id="supplierId" @product-changed="chosenProductId = $event" /> </template> <DxItem template="order-history"> <DxLabel text="Order History"/> </DxItem> <template #order-history="{ data }"> <OrderHistory :product-id="chosenProductId" /> </template> </DxForm> </template> <script> import { DxForm, DxItem, DxLabel } from 'devextreme-vue/form'; import ProductSelectBox from './ProductSelectBox.vue'; import OrderHistory from './OrderHistory.vue'; export default { components: { DxForm, DxItem, DxLabel, ProductSelectBox, OrderHistory, }, props: { supplierId: { type: Number, default: null, }, }, data() { return { chosenProductId: null, }; }, }; </script> <template> <DxSelectBox :defer-rendering="false" :data-source="dataSource" :value="value" value-expr="ProductID" display-expr="ProductName" @valueChanged="$emit('product-changed', $event.value)" /> </template> <script> import DxSelectBox from 'devextreme-vue/select-box'; import { createStore } from 'devextreme-aspnet-data-nojquery'; const url = 'https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView'; export default { components: { DxSelectBox }, props: { supplierId: { type: Number, default: null, }, }, data() { return { dataSource: createStore({ key: 'ProductID', loadParams: { SupplierID: this.supplierId }, loadUrl: `${url}/GetProductsBySupplier`, onLoaded: this.setDefaultValue, }), value: null, }; }, methods: { setDefaultValue(items) { const firstItem = items[0]; if (firstItem && this.value === null) { this.value = firstItem.ProductID; } }, }, }; </script> import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app'); <!DOCTYPE html> <html> <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=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/22.1.5/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/22.1.5/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.js"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app" /> </div> </body> </html> #gridContainer { height: 620px; } .dx-datagrid-rowsview .dx-master-detail-row:not(.dx-datagrid-edit-form) > .dx-datagrid-group-space, .dx-datagrid-rowsview .dx-master-detail-row:not(.dx-datagrid-edit-form) .dx-master-detail-cell { background-color: transparent; } .form-container { padding: 20px; } .address-form label { font-weight: bold; } window.config = { transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader', }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme-aspnet-data-nojquery': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', }, map: { 'vue': 'npm:vue@3.0.0/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.0.15/index.js', 'devextreme-aspnet-data-nojquery': 'npm:devextreme-aspnet-data-nojquery@2.8.6/index.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.0/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@22.1.5/cjs', 'devextreme-vue': 'npm:devextreme-vue@22.1.5', 'jszip': 'npm:jszip@3.7.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.5.16/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.1.63/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.32/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.11', 'inferno': 'npm:inferno@7.4.4/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat@7.4.11/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode@7.4.11/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class@7.4.11/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras@7.4.11/dist/inferno-extras.min.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.7.1/standalone.js', 'prettier/parser-html': 'npm:prettier@2.7.1/parser-html.js', }, packages: { 'devextreme-vue': { main: 'index.js', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.11/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, }, }; System.config(window.config); Copyright © 2011-2022 Developer Express Inc. All trademarks or registered trademarks are property of their respective owners. Your Privacy - Legal Statements Licensing Follow us