Your search did not match any results.
Data Grid

Advanced Master-Detail View

This demo illustrates an advanced master-detail view in the DataGrid widget. Master rows represent suppliers. Detail sections contain TabPanel widgets 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.

Copy to CodePen
Apply
Reset
const url = "https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView"; $(function(){ $("#gridContainer").dxDataGrid({ showBorders: true, dataSource: DevExpress.data.AspNet.createStore({ key: "SupplierID", loadUrl: url + "/GetSuppliers" }), paging: { pageSize: 15 }, remoteOperations: true, columns: [ "ContactName", "ContactTitle", "CompanyName", "City", "Country" ], masterDetail: { enabled: true, template: masterDetailTemplate } }); }); function masterDetailTemplate(_, masterDetailOptions) { return $("<div>").dxTabPanel({ items: [{ title: "Orders", template: createOrdersTabTemplate(masterDetailOptions.data) }, { title: "Address", template: createAddressTabTemplate(masterDetailOptions.data), }] }); } function createOrdersTabTemplate(masterDetailData) { return function() { let orderHistoryDataGrid; function onProductChanged(productID) { orderHistoryDataGrid.option("dataSource", createOrderHistoryStore(productID)); } function onDataGridInitialized(e) { orderHistoryDataGrid = e.component; } return $("<div>").addClass("form-container").dxForm({ labelLocation: "top", items: [{ label: { text: "Product" }, template: createProductSelectBoxTemplate(masterDetailData, onProductChanged) }, { label: { text: "Order History" }, template: createOrderHistoryTemplate(onDataGridInitialized) }] }); }; } function createProductSelectBoxTemplate(masterDetailData, onProductChanged) { return function() { return $("<div>").dxSelectBox({ dataSource: DevExpress.data.AspNet.createStore({ key: "ProductID", loadParams: { SupplierID: masterDetailData.SupplierID }, loadUrl: url + "/GetProductsBySupplier" }), valueExpr: "ProductID", displayExpr: "ProductName", deferRendering: false, onContentReady: function(e) { let firstItem = e.component.option("items[0]"); if(firstItem) { e.component.option("value", firstItem.ProductID); } }, onValueChanged: function(e) { onProductChanged(e.value) } }); }; } function createOrderHistoryTemplate(onDataGridInitialized) { return function() { return $("<div>").dxDataGrid({ onInitialized: onDataGridInitialized, paging: { pageSize: 5 }, showBorders: true, columns: [ "OrderID", { dataField: "OrderDate", dataType: "date" }, "ShipCountry", "ShipCity", { dataField: "UnitPrice", format: "currency" }, "Quantity", { dataField: "Discount", format: "percent" } ], summary: { totalItems: [{ column: "UnitPrice", summaryType: "sum", valueFormat: { format: "currency", precision: 2 } }, { column: "Quantity", summaryType: "count" }] } }); }; } function createAddressTabTemplate(data) { return function() { return $("<div>").addClass("address-form form-container").dxForm({ formData: data, colCount: 2, customizeItem: function(item) { item.template = formItemTemplate; }, items: ["Address", "City", "Region", "PostalCode", "Country", "Phone"] }); }; } function formItemTemplate(item) { return $("<span>").text(item.editorOptions.value); } function createOrderHistoryStore(productID) { return DevExpress.data.AspNet.createStore({ key: "OrderID", loadParams: { ProductID: productID }, loadUrl: url + "/GetOrdersByProduct" }); }
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <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" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/19.2.4/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/19.2.4/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://cdn3.devexpress.com/jslib/19.2.4/js/dx.all.js"></script> <script src="https://unpkg.com/devextreme-aspnet-data@2.5.1/js/dx.aspnet.data.js"></script> <script src="index.js"></script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="gridContainer"></div> </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; }