var DemoApp = angular.module('DemoApp', ['dx']);
const url = "https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView";
DemoApp.controller('DemoController', function DemoController($scope) {
$scope.gridOptions = {
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: "masterDetail"
}
};
$scope.getTabPanelOptions = function(masterDetailData) {
return {
items: [{
title: "Orders",
template: "ordersTab"
}, {
title: "Address",
template: "addressTab",
}]
};
};
$scope.getAddressTabOptions = function(data) {
return {
formData: data,
colCount: 2,
customizeItem: function(item) {
item.template = "formItemTemplate";
},
items: ["Address", "City", "Region", "PostalCode", "Country", "Phone"]
};
}
});
DemoApp.controller("OrdersTabController", function OrdersTabController($scope) {
function createOrderHistoryStore(productID) {
return DevExpress.data.AspNet.createStore({
key: "OrderID",
loadParams: { ProductID: productID },
loadUrl: url + "/GetOrdersByProduct"
});
}
$scope.getOrdersTabOptions = function(masterDetailData) {
return {
labelLocation: "top",
items: [{
label: { text: "Product" },
template: "productSelectBox"
}, {
label: { text: "Order History" },
template: "orderHistory"
}]
};
};
$scope.getSelectBoxOptions = function(masterDetailData) {
return {
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) {
$scope.dataSource = createOrderHistoryStore(e.value);
}
};
};
$scope.orderHistoryDataGridOptions = {
bindingOptions: {
dataSource: {
deep: false,
dataPath: "dataSource"
}
},
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"
}]
}
};
});
<!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://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>
<script>window.angular || document.write(decodeURIComponent('%3Cscript src="js/angular.min.js"%3E%3C/script%3E'))</script>
<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" ng-app="DemoApp" ng-controller="DemoController">
<div dx-data-grid="gridOptions" dx-item-alias="masterDetailItem" id="gridContainer">
<div data-options="dxTemplate: {name: 'masterDetail'}">
<div dx-tab-panel="getTabPanelOptions(masterDetailItem.data)">
<div data-options="dxTemplate: {name: 'ordersTab'}" >
<div ng-controller="OrdersTabController">
<div dx-form="getOrdersTabOptions(masterDetailItem.data)" class="form-container">
<div data-options="dxTemplate: {name: 'productSelectBox'}">
<div dx-select-box="getSelectBoxOptions(masterDetailItem.data)"></div>
</div>
<div data-options="dxTemplate: {name: 'orderHistory'}">
<div dx-data-grid="orderHistoryDataGridOptions"></div>
</div>
</div>
</div>
</div>
<div data-options="dxTemplate: {name: 'addressTab'}" >
<div dx-form="getAddressTabOptions(masterDetailItem.data)" dx-item-alias="formItem" class="address-form form-container">
<div data-options="dxTemplate: {name: 'formItemTemplate'}">
<span>{{formItem.editorOptions.value}}</span>
</div>
</div>
</div>
</div>
</div>
</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;
}