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.5.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/20.2.5/css/dx.common.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.5/css/dx.light.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="https://cdn3.devexpress.com/jslib/20.2.5/js/dx.all.js"></script>
<script src="https://unpkg.com/devextreme-aspnet-data@2.7.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;
}