Skip to main content Skip to footer

How To Display Master Detail Data with TagHelpers, Part I

Displaying data that has master detail relationship is not a trivial task in MVC, but you can achieve it with several approaches. In this series, I'll demonstrate two ways of displaying master and detail data, and then end with a third article discussing an upcoming feature in FlexGrid which makes this task very easy.

1. All data transferred to client

In this article we'll consider a list of customer objects that have a list of Order objects as property. We'll also take a look at currency management, which the MVC Edition CollectionView provides out of the box.

2. Data present on server and client

In the next article we'll consider two tables, Customer and Orders; some data can be on server and some on client. We'll use different actions to fetch related data.

3.Nested FlexGrid

Finally, we'll see how FlexGrid makes this task a trivial one with nested grids.

All Data transferred to client

See currency in action:
ComponentOne Studio MVC TagHelpers Master Detail
Let's walk through implementing this mechanism.

Create the Data

Here is a Customer-and-Order class example. Note that Customer class has Orders property, which is a list of Orders the customer has placed. The Customer class has a "GetData" method that creates some dummy data.

Customer Class


    using System;  
    using System.Collections.Generic;  

    public class Customer  
    {  
        public int CustomerID { get; set; }  
        public string CompanyName { get; set; }  
        public string City { get; set; }  
        public string Region { get; set; }  
        public List Orders { get; set; }  
        List Cities = new List { "New York", "London", "Tokyo", "Delhi", "Sydney" };  

       public List GetData()  
        {  
            List list = new List();  
            Random rn = new Random();  

            for (int i = 0; i <= 5; i++)  
            {  


                Customer item = new Customer();  
                item.CustomerID = 1200 + i;  
                item.CompanyName = "ABC" + i;  

                var index = rn.Next(Cities.Count);  
                item.City = Cities[index];  
                item.Orders = new List();  
                for (int j = 0; j <= 5; j++)  
                {  
                    var ind = rn.Next(Cities.Count);  
                    Order order = new Order();  
                    order.OrderID = 100 + j;  
                    order.CustomerID = 1200 + i;  
                    order.EmployeeID = 1000 + i;  
                    order.OrderDate = new DateTime(2015, 07, j + 1);  
                    order.ShipCity = Cities[ind];  

                    item.Orders.Add(order);  
                }  
                list.Add(item);  

            }  
            return list;  
        }  

    }  

Order Class


using System;  
    using System.Collections.Generic;  

    public partial class Order  
    {  
        public int OrderID { get; set; }  
        public int CustomerID { get; set; }  
        public Nullable EmployeeID { get; set; }  
        public Nullable OrderDate { get; set; }  
        public string ShipCity { get; set; }  

    }  

Provide Data to View

Here I list the "MasterDetail" Controller and the action that returns data to view.


public class MasterDetail : Controller  
    {  
        // GET: //  
        public IActionResult Index()  
        {  
            Customer customerOrder = new Customer();  
            return View(customerOrder.GetData());  

        }  
    }  

Show Me The Data

Here's where the task gets non-trivial. We need to show Customer data inside a FlexGrid, and the related Orders inside another FlexGrid. We also want currency: when when we select a row in Customer FlexGrid, the Orders display in detail FlexGrid.

Customer FlexGrid


@model  List  


Customers







Orders Nothing too in the above code—we simply bind CustomerGrid with the Model using c1-item-source tag.

#### Orders FlexGrid


Orders


It's important to note that the above Orders FlexGrid has defined columns, but does not data bind the FlexGrid. We're going to bind the Orders FlexGrid client side and take advantage of the CollectionView client API.
  var grid, cv,dGrid;  
  c1.mvc.Utils.documentReady(function ()  
  {  
      grid = wijmo.Control.getControl("#CustomerGrid");  
      cv = grid.collectionView;  //Get the reference of CollectionView datasource from Customers FlexGrid  
      dGrid = wijmo.Control.getControl('#detailGrid'); //Get detail FlexGrid  
   });  
In the above code we've referenced the datasource of Customer FlexGrid in a variable named "cv". Here's the interesting part: we'll now bind the Orders FlexGrid and also enable currency by adding an event handler "currentChanged" to the CollectionView "cv". In the "currentChanged" event we call a method which binds the Orders FlexGrid with the selected Customers' Orders. Here's the complete Javascript code, including the above script.
  var grid, cv,dGrid;  
  c1.mvc.Utils.documentReady(function ()  
  {  
      grid = wijmo.Control.getControl("#CustomerGrid");  
      cv = grid.collectionView; //Get the reference of CollectionView datasource from Customers FlexGrid  
      dGrid = wijmo.Control.getControl('#detailGrid'); //Get reference for Orders Grid  
      cv.currentChanged.addHandler(updateDetails);  //Add handler for collectionView currency changed event  
      cv.moveCurrentToFirst(); //Select first Customer  
  });  

  function updateDetails() {  
      var item = cv.currentItem;  //Get the current selected Customer  
      dGrid.itemsSource = item.Orders;  //Bind the Orders FlexGrid  
  };  
Here's the complete code for the View:

@model List

  var grid, cv,dGrid;  
  c1.mvc.Utils.documentReady(function ()  
  {  
      grid = wijmo.Control.getControl("#CustomerGrid");  
      cv = grid.collectionView;  
      dGrid = wijmo.Control.getControl('#detailGrid');  
      cv.currentChanged.addHandler(updateDetails);  
      cv.moveCurrentToFirst();  
  });  

  function updateDetails() {  
      var item = cv.currentItem;  
      dGrid.itemsSource = item.Orders;  
  };  

Customers

Orders


This implementation is also possible with [HtmlHelpers](http://demos.componentone.com/aspnet/mvcexplorer) in MVC 3,4,5. Most of the code would remain same except how the FlexGrid is declared.  
Please note [TagHelpers](http://demos.componentone.com/aspnet/taghelperexplorer) are a work in progress. You'll be able to try out these controls in MVC6 with Beta7 support in September 2015.

### [Read more about TagHelpers in MVC Edition >>](http://our.componentone.com/tag/taghelpers/)




MESCIUS inc.

comments powered by Disqus