const DemoApp = angular.module('DemoApp', ['dx']);
const url = 'https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView';
DemoApp.controller('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 () {
return {
items: [{
title: 'Orders',
template: 'ordersTab',
}, {
title: 'Address',
template: 'addressTab',
}],
};
};
$scope.getAddressTabOptions = function (data) {
return {
formData: data,
colCount: 2,
customizeItem(item) {
item.template = 'formItemTemplate';
},
items: ['Address', 'City', 'Region', 'PostalCode', 'Country', 'Phone'],
};
};
});
DemoApp.controller('OrdersTabController', ($scope) => {
function createOrderHistoryStore(productID) {
return DevExpress.data.AspNet.createStore({
key: 'OrderID',
loadParams: { ProductID: productID },
loadUrl: `${url}/GetOrdersByProduct`,
});
}
$scope.getOrdersTabOptions = function () {
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(e) {
const firstItem = e.component.option('items[0]');
if (firstItem) {
e.component.option('value', firstItem.ProductID);
}
},
onValueChanged(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/22.2.6/css/dx.light.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/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/22.2.6/js/dx.all.js"></script>
<script src="https://unpkg.com/devextreme-aspnet-data@2.9.0/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;
}