Your search did not match any results.

Advanced Master-Detail View

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

Backend API
@(Html.DevExtreme().DataGrid<DevExtreme.NETCore.Demos.Models.Northwind.Supplier>() .ID("gridContainer") .ShowBorders(true) .DataSource(d => d.Mvc().Controller("DataGridAdvancedMasterDetailView").LoadAction("GetSuppliers").Key("SupplierID")) .Paging(p => p.PageSize(15)) .Columns(columns => { columns.AddFor(m => m.ContactName); columns.AddFor(m => m.ContactTitle); columns.AddFor(m => m.CompanyName); columns.AddFor(m => m.City); columns.AddFor(m => m.Country); }) .MasterDetail(m => m .Enabled(true) .Template(new TemplateName("gridContainer-details")) ) ) @using(Html.DevExtreme().NamedTemplate("gridContainer-details")) { @(Html.DevExtreme().TabPanel() .Items(items => { items.Add() .Title("Orders") .Template(new TemplateName("gridContainer-details-tab1Template")) .Option("tabExtras", new { supplierID = new JS("data.SupplierID") }); items.Add() .Title("Address") .Template(new TemplateName("gridContainer-details-tab2Template")) .Option("tabExtras", new JS("data")); }) ) } @using(Html.DevExtreme().NamedTemplate("gridContainer-details-tab1Template")) { @(Html.DevExtreme().Form() .ElementAttr("class", "form-container") .FormData(new JS("tabExtras")) .LabelLocation(FormLabelLocation.Top) .Items(items => { items.AddSimple() .Label(l => l.Text("Product")) .Editor(e => e.SelectBox() .DataSource(d => d.Mvc() .Controller("DataGridAdvancedMasterDetailView") .LoadAction("GetProductsBySupplier") .LoadParams(new { supplierID = new JS("tabExtras.supplierID") }) .Key("ProductID") ) .InputAttr("aria-label", "Product") .ValueExpr("ProductID") .DisplayExpr("ProductName") .DeferRendering(false) .OnContentReady(@<text> function(e) { var firstItem = e.component.option("items[0]"); if(firstItem) { e.component.option("value", firstItem.ProductID); } } </text>) .OnSelectionChanged(@<text> function(e) { tabExtras.productID = e.selectedItem.ProductID; $("#gridContainer-orderHistoryGrid-" + tabExtras.supplierID).dxDataGrid("instance").refresh(); } </text>) ); items.AddSimple() .Label(l => l.Text("Order History")) .Template(new TemplateName("gridContainer-details-tab1-gridTemplate")); }) ) } @using(Html.DevExtreme().NamedTemplate("gridContainer-details-tab1-gridTemplate")) { @(Html.DevExtreme().DataGrid() .ID(new JS("'gridContainer-orderHistoryGrid-' + component.option('formData').supplierID")) .ShowBorders(true) .DataSource(d => d.Mvc() .Controller("DataGridAdvancedMasterDetailView") .LoadAction("GetOrdersByProduct") .LoadParams(new { productID = new JS("function() { return component.option('formData').productID }") }) ) .Paging(p => p.PageSize(5)) .Columns(columns => { columns.Add().DataField("OrderID"); columns.Add().DataField("OrderDate").DataType(GridColumnDataType.Date); columns.Add().DataField("ShipCountry"); columns.Add().DataField("ShipCity"); columns.Add().DataField("UnitPrice").Format(Format.Currency); columns.Add().DataField("Quantity"); columns.Add().DataField("Discount").Format(Format.Percent); }) .Summary(s => s .TotalItems(totalItems => { totalItems.Add() .Column("UnitPrice") .SummaryType(SummaryType.Sum) .ValueFormat(f => f .Currency("USD") .Precision(2) ); totalItems.Add() .Column("Quantity") .SummaryType(SummaryType.Count); }) ) ) } @using(Html.DevExtreme().NamedTemplate("gridContainer-details-tab2Template")) { var formItemTemplate = "<%- editorOptions.value %>"; @(Html.DevExtreme().Form() .ElementAttr("class", "address-form form-container") .FormData(new JS("tabExtras")) .ColCount(2) .Items(items => { items.AddSimple().DataField("Address").Template(formItemTemplate); items.AddSimple().DataField("City").Template(formItemTemplate); items.AddSimple().DataField("Region").Template(formItemTemplate); items.AddSimple().DataField("PostalCode").Template(formItemTemplate); items.AddSimple().DataField("Country").Template(formItemTemplate); items.AddSimple().DataField("Phone").Template(formItemTemplate); }) ) }
using DevExtreme.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers { public class DataGridController : Controller { public ActionResult AdvancedMasterDetailView() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.NETCore.Demos.Models.Northwind; using Microsoft.AspNetCore.Mvc; using System; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DataGridAdvancedMasterDetailViewController : Controller { NorthwindContext _nwinds; public DataGridAdvancedMasterDetailViewController(NorthwindContext nwinds) { _nwinds = nwinds; } [HttpGet] public object GetSuppliers(DataSourceLoadOptions options) { return DataSourceLoader.Load(_nwinds.Suppliers, options); } [HttpGet] public object GetProductsBySupplier(int supplierID, DataSourceLoadOptions options) { return DataSourceLoader.Load(_nwinds.Products.Where(p => p.SupplierID == supplierID), options); } [HttpGet] public object GetOrdersByProduct(int productID, DataSourceLoadOptions options) { var query = from i in _nwinds.Order_Details where i.ProductID == productID join j in _nwinds.Orders on i.OrderID equals j.OrderID select new { i.OrderID, j.OrderDate, j.ShipCountry, j.ShipCity, i.UnitPrice, i.Quantity, i.Discount }; return DataSourceLoader.Load(query, options); } } }
#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; }