In an earlier post I described how to display Master Detail data with TagHelpers when all data is present on client. In this article, I'll describe the steps needed to display data from related tables when the data may reside on server. See currency in action. See currency in action. I've created a new project using the "C1 ASP.NET MVC 6 Web Application" template. This automatically configures the project with all the packages and resource registrations. MVC6 Template For detail on using default MVC 6 template please refer to the documentation.

The Data

The data for this example comes from the Northwind database. I'm using Entity Framework to get the Customers and Orders data. The two tables are related by CustomerID column, as each customer may have placed many orders.

Provide the Data

Here I list the controller actions that serve the Customer and related Orders data.


public partial class FlexGridController : Controller  
    {  
        // GET: //  
        public ActionResult MasterDetail()  
        {  
            return View(\_db.Customers.Take(10).ToList());  // \_db is an instance of C1NWindEntities  
        }  

        public ActionResult DetailData([C1JsonRequest] CollectionViewRequest requestData)  
        {  
            string customerID = requestData.ExtraRequestData["CustomerID"].ToString(); //get the current selected Customer.  
            return this.C1Json(CollectionViewHelper.Read(requestData, _db.Orders.Where(s => s.CustomerID == customerID).ToList()));  
        }  
    }  

In the "MasterDetail" action we're returning 10 customers to the View. In the "DetailData" action, first we're getting the CustomerID for which the detail has been requested. Then we're returning the related Orders by comparing and getting only those orders which were placed by this "CustomerID".

Show Me The Data

Let's start configuring the view by initialising FlexGrid to display Customer data.


@using TagHelperExplorer.Models  
@using C1.Web.Mvc.Grid  
@model IEnumerable  


Customers










Next, we'll initialise another FlexGrid to display Order data:



Orders






It's interesting to note the binding of "Orders" FlexGrid: it has a collection-query-data tag that takes a javascript function that returns "CustomerID" for which orders need to be displayed. Here's the "getCustomerID" javascript function:


function getCustomerID(sender, e) {  
       if (e.extraRequestData == null) {  
            e.extraRequestData = {};  
        }  
       grid = wijmo.Control.getControl("#Customer");  //Get the reference for "Customers" FlexGrid  
         if (grid) {  
            currentItem = grid.collectionView.currentItem;  //Get the selected Customer in Customers FlexGrid  
            e.extraRequestData["CustomerID"] = currentItem ? currentItem.CustomerID : ""; //assign CustomerID to return argument  
        }  

This function returns the "CustomerID" of the current selected Customer in "Customer" FlexGrid. This, however, does not solve our problem. We want to display related orders when selection changes. This requires some currency to be tracked, and we can achieve this by refreshing the "Orders" FlexGrid "collectionView" when the current selection changes for the "Customers" FlexGrid. The collectionView can be refreshed in the "currentChanged" event handler of "Customer" FlexGrid's collectionView.


  var grid, cv,detail,cvDetail;  
        c1.mvc.Utils.documentReady(function () {  
        grid = wijmo.Control.getControl("#Customer");  //Get reference for Customers FlexGrid  
        cv = grid.collectionView;  //Get reference for Customers FlexGrid collectionView  
        cv.currentChanged.addHandler(getOrders);  //Add handler to Customers FlexGrid collectionView  
        cv.moveCurrentToFirst();  
       });  

        function getOrders() {  
            detail = wijmo.Control.getControl("#Orders");  
            if (cvDetail == null)  
            {  
                cvDetail = detail.collectionView;  //Get reference for Orders FlexGrid collectionView  
            }  

        cvDetail.refresh();  //refresh the collectionView so that it performs a full refresh of the data.  
      }  

Here's the complete script:



    var grid, cv,detail,cvDetail;  
        c1.mvc.Utils.documentReady(function () {  
        grid = wijmo.Control.getControl("#Customer");  
        cv = grid.collectionView;  
        cv.currentChanged.addHandler(getOrders);  
        cv.moveCurrentToFirst();  
       });  

        function getOrders() {  
            detail = wijmo.Control.getControl("#Orders");  
            if (cvDetail == null)  
            {  
                cvDetail = detail.collectionView;  
            }  

        cvDetail.refresh();  
      }  

    function getCustomerID(sender, e) {  
       if (e.extraRequestData == null) {  
            e.extraRequestData = {};  
        }  
       grid = wijmo.Control.getControl("#Customer");  
         if (grid) {  
            currentItem = grid.collectionView.currentItem;  
            e.extraRequestData["CustomerID"] = currentItem ? currentItem.CustomerID : "";  
         }  
    }  


Here's the complete code for the View:


@using TagHelperExplorer.Models  
@using C1.Web.Mvc.Grid  
@model IEnumerable  


    var grid, cv,detail,cvDetail;  
        c1.mvc.Utils.documentReady(function () {  
        grid = wijmo.Control.getControl("#Customer");  
        cv = grid.collectionView;  
        cv.currentChanged.addHandler(getOrders);  
        cv.moveCurrentToFirst();  
       });  

        function getOrders() {  
            detail = wijmo.Control.getControl("#Orders");  
            if (cvDetail == null)  
            {  
                cvDetail = detail.collectionView;  
            }  

        cvDetail.refresh();  
      }  

    function getCustomerID(sender, e) {  
       if (e.extraRequestData == null) {  
            e.extraRequestData = {};  
        }  
       grid = wijmo.Control.getControl("#Customer");  
         if (grid) {  
            currentItem = grid.collectionView.currentItem;  
            e.extraRequestData["CustomerID"] = currentItem ? currentItem.CustomerID : "";  
         }  
    }  


Customers











Orders






This implementation is also possible with HtmlHelpers in MVC 3,4,5. Most of the code would remain the same except how the FlexGrid is declared. We'll add this example to MVCExplorer sample for easy reference.
Please note TagHelpers 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 ASP.NET MVC Edition >>

Read more about ComponentOne Studio MVC Edition>>