# Client Detail Templates

The Telerik UI Grid for ASP.NET MVC enables you to show additional information for a data item by setting the detail template of the Grid.

For a runnable example, refer to the [demo on detail templates in the Grid](https://demos.telerik.com/aspnet-mvc/grid/detailtemplate).

To configure the client detail template:

1. [Define the client details](https://www.telerik.com/aspnet-mvc/documentation/html-helpers/data-management/grid/templates/client-detail-template#defining-the-client-details)
2. [Set the client hierarchy](https://www.telerik.com/aspnet-mvc/documentation/html-helpers/data-management/grid/templates/client-detail-template#setting-the-client-hierarchy)

## Defining the Client Details

To configure the Grid for ASP.NET MVC to display additional details of the **Product** entity from the **Northwind** database:

1. Create a new ASP.NET MVC application. If you have installed the [Telerik UI for ASP.NET MVC Visual Studio Extensions](https://www.telerik.com/aspnet-mvc/documentation/vs-integration/introduction), create a Telerik UI for ASP.NET MVC application. Name the application `KendoGridClientDetailTemplate`. If you have chosen not to use the Telerik UI for ASP.NET MVC Visual Studio Extensions, follow the steps from the [introductory article](https://www.telerik.com/aspnet-mvc/documentation/getting-started-mvc/first-steps) to add Telerik UI for ASP.NET MVC to the application.

2. Add a new `Entity Framework Data Model`. Right-click the `~/Models` folder in the solution explorer and pick **Add** > **New Item**. Choose **Data** > **ADO.NET Entity Data Model** in the **Add New Item** dialog. Name the model `Northwind.edmx` and click **Next**. This starts the **Entity Data Model Wizard**.

   ![UI for ASP.NET MVC A new entity data model](https://www.telerik.com/aspnet-mvc/documentation/assets/1286540ae776a0b9803b365ff9a0c775/grid-entity-data-model.png)

3. Select **Generate from database** and click **Next**. Configure a connection to the **Northwind** database. Click **Next**.

   ![UI for ASP.NET MVC Choosing the connection](https://www.telerik.com/aspnet-mvc/documentation/assets/1b29022c17fddc909b4d7bd3de4fbdce/grid-binding-choose-data-connection.png)

4. Choose the **Products** table from the **Which database objects do you want to include in your model?**. Leave all other options as set by default. Click **Finish**.

   ![UI for ASP.NET MVC Choosing the Products table in the database objects](https://www.telerik.com/aspnet-mvc/documentation/assets/9b3c6e48269198e2986c090f51010f6a/grid-binding-choose-database-objects.png)

5. Open `HomeController.cs` and add a new action method which will return the Products as JSON. The Grid makes Ajax requests to this action.

   ```CS
   public ActionResult Products_Read()
   {
   }
   ```

6. Add a new parameter of type `DataSourceRequest` to the action. This parameter will contain the current Grid request information—page, sort, group, and filter. Decorate that parameter with the `DataSourceRequestAttribute`. This attribute will populate the `DataSourceRequest` object from the posted data.

   ```CS
   public ActionResult Products_Read([DataSourceRequest]DataSourceRequest request)
   {
   }
   ```

7. Use the `ToDataSourceResult` extension method to convert the Products to a `DataSourceResult` object. That extension method will page, filter, sort, or group your data using the information provided by the `DataSourceRequest` object.

   ```CS
   public ActionResult Products_Read([DataSourceRequest]DataSourceRequest request)
   {
       using (var northwind = new NorthwindEntities())
       {
           IQueryable<Product> products = northwind.Products;
           DataSourceResult result = products.ToDataSourceResult(request);
       }
   }
   ```

8. Return the `DataSourceResult` as JSON. Configure the Grid for Ajax binding.

   ```CS
   public ActionResult Products_Read([DataSourceRequest]DataSourceRequest request)
   {
       using (var northwind = new NorthwindEntities())
       {
           IQueryable<Product> products = northwind.Products;
           DataSourceResult result = products.ToDataSourceResult(request);
           return Json(result);
       }
   }
   ```

9. In the view, configure the Grid to use the action method created in the previous steps.

   ```Razor HtmlHelper
       @(Html.Kendo().Grid<KendoGridClientDetailTemplate.Models.Product>()
             .Name("grid")
             .DataSource(dataSource => dataSource
                 .Ajax()
                 .Read(read => read.Action("Products_Read", "Home"))
              )
             .Columns(columns =>
             {
                 columns.Bound(product => product.ProductID);
                 columns.Bound(product => product.ProductName);
             })
             .Pageable()
       )
   ```

10. Define the client template using the [Kendo UI for jQuery template](https://docs.telerik.com/kendo-ui/framework/templates/overview) syntax. The context of the template is the data item—Product entity— bound to the Grid.

    > Each `#` symbol that is not part of a template expression—`#: #`, `# #` or `#= #`—must be escaped—`\\#`.

    ```JS
    <script id="client-template" type="text/x-kendo-template">
        <div>ProductID: #: ProductID #</div>
        <div>ProductName: #: ProductName #</div>
        <div>UnitsInStock: #: UnitsInStock #</div>
        <div>UnitPrice: #: UnitPrice #</div>
        <div>UnitsOnOrder: #: UnitsOnOrder #</div>
        <div>Discontinued: #: Discontinued #</div>
    </script>
    ```

11. Specify the `id` of the template by using the `ClientDetailTemplateId` method.

    ```Razor HtmlHelper
        @(Html.Kendo().Grid<KendoGridClientDetailTemplate.Models.Product>()
              .Name("grid")
              .DataSource(dataSource => dataSource
                  .Ajax()
                  .Read(read => read.Action("Products_Read", "Home"))
               )
              .Columns(columns =>
              {
                  columns.Bound(product => product.ProductID);
                  columns.Bound(product => product.ProductName);
              })
              .Pageable()
              .ClientDetailTemplateId("client-template")
        )
    ```

12. Build and run the project.

    ![UI for ASP.NET MVC The final result is a Grid with detail template](https://www.telerik.com/aspnet-mvc/documentation/assets/fc491596143fedb7d7beaf614294698b/grid-detail-template.png)

To download the Visual Studio Project, refer to [this GitHub repository](https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Areas/GridClientDetailTemplate).

## Setting the Client Hierarchy

To configure the Grid for ASP.NET MVC to display all **Product** entities that are available per the **Category** entity from the **Northwind** database:

1. Create a new ASP.NET MVC application. If you have installed the [Telerik UI for ASP.NET MVC Visual Studio Extensions](https://www.telerik.com/aspnet-mvc/documentation/vs-integration/introduction), create a Telerik UI for ASP.NET MVC application. Name the application `KendoGridClientHierarchy`. If you have chosen not to use the Telerik UI for ASP.NET MVC Visual Studio Extensions, follow the steps from the [introductory article](https://www.telerik.com/aspnet-mvc/documentation/getting-started-mvc/first-steps) to add Telerik UI for ASP.NET MVC to the application.

2. Add a new `Entity Framework Data Model`. Right-click the `~/Models` folder in the solution explorer and pick **Add** > **New Item**. Choose **Data** > **ADO.NET Entity Data Model** in the **Add New Item** dialog. Name the model `Northwind.edmx` and click **Next**. This starts the **Entity Data Model Wizard**.

   ![UI for ASP.NET MVC A new entity data model](https://www.telerik.com/aspnet-mvc/documentation/assets/1286540ae776a0b9803b365ff9a0c775/grid-entity-data-model.png)

3. Select **Generate from database** and click **Next**. Configure a connection to the **Northwind** database. Click **Next**.

   ![UI for ASP.NET MVC Choosing the connection](https://www.telerik.com/aspnet-mvc/documentation/assets/1286540ae776a0b9803b365ff9a0c775/grid-entity-data-model.png)

4. Choose the **Products** and **Categories** tables from **Which database objects do you want to include in your model?**. Leave all other options as set by default. Click **Finish**.

5. Open `HomeController.cs` and add a new action method which will return the **Category** entities as JSON. The Grid makes Ajax requests to this action.

   ```C#
   public ActionResult Categories_Read()
   {
   }
   ```

6. Add a new parameter of type `DataSourceRequest` to the action. This parameter will contain the current grid request information - page, sort, group and filter. Decorate that parameter with the `DataSourceRequestAttribute`. That attribute will populate the `DataSourceRequest` object from the posted data.

   ```C#
   public ActionResult Categories_Read([DataSourceRequest]DataSourceRequest request)
   {
   }
   ```

7. Use the `ToDataSourceResult` extension method to convert the Categories to a `DataSourceResult` object. That extension method will page, filter, sort, or group your data using the information provided by the `DataSourceRequest` object.

   ```C#
   public ActionResult Categories_Read([DataSourceRequest]DataSourceRequest request)
   {
       using (var northwind = new NorthwindEntities())
       {
           IQueryable<Category> categories = northwind.Categories;
           // Flatten the Category to avoid circular references during JSON serialization.
           DataSourceResult result = categories.ToDataSourceResult(request, category => new {
               category.CategoryID,
               category.CategoryName
           });
       }
   }
   ```

8. Return the `DataSourceResult` as JSON. Now let's configure the Grid for AJAX binding.

   ```C#
   public ActionResult Categories_Read([DataSourceRequest]DataSourceRequest request)
   {
       using (var northwind = new NorthwindEntities())
       {
           IQueryable<Category> categories = northwind.Categories;
           // Flatten the Category to avoid circular references during JSON serialization.
           DataSourceResult result = categories.ToDataSourceResult(request, category => new {
               category.CategoryID,
               category.CategoryName
           });
           return Json(result);
       }
   }
   ```

9. Open `HomeController.cs` and add a new action method which will return the **Product** entities for a given category as JSON. The child Grid makes Ajax requests to this action.

   ```C#
   public ActionResult Products_Read([DataSourceRequest]DataSourceRequest request, int categoryId)
   {
       using (var northwind = new NorthwindEntities())
       {
           IQueryable<Product> products = northwind.Products.Where(product => product.CategoryID == categoryId);
           // Flatten the Product to avoid circular references during JSON serialization
           DataSourceResult result = products.ToDataSourceResult(request, product => new {
               product.ProductID,
               product.ProductName
           });
           return Json(result);
       }
   }
   ```

10. In the view, configure the Grid for Ajax binding to `Categories_Read`.

    ```Razor HtmlHelper
        @(Html.Kendo().Grid<KendoGridClientHierarchy.Models.Category>()
              .Name("grid")
              .Columns(columns =>
              {
                  columns.Bound(category => category.CategoryID);
                  columns.Bound(category => category.CategoryName);
              })
              .DataSource(dataSource =>
                dataSource.Ajax().Read(read => read.Action("Categories_Read", "Home"))
              )
        )
    ```

11. Define the client template using [Kendo UI Template](https://docs.telerik.com/kendo-ui/framework/templates/overview) syntax. The context of the template is the **Category** entity bound to the Grid. The template itself contains another Grid bound to the `Products_Read` action.

    > * Always call the `ToClientTemplate` method when using Telerik UI for ASP.NET MVC helpers in a client template.
    > * Escape the `#` characters used for a template expression when using a column `ClientTemplate` in a detail template, so that the expression is evaluated in the correct context.

    ```Razor HtmlHelper
        <script id="client-template" type="text/x-kendo-template">
            @(Html.Kendo().Grid<KendoGridClientHierarchy.Models.Product>()
                    .Name("grid_#=CategoryID#") // make sure the Name is unique
                    .Columns(columns =>
                    {
                        columns.Bound(product => product.ProductID);
                        columns.Bound(product => product.ProductName).ClientTemplate("<strong>\\#:ProductName\\#</strong>"); // escape the "#" characters
                    })
                    .DataSource(dataSource =>
                        // Make a request to Products_Read and provide the current CategoryID as a route parameter.
                        dataSource.Ajax().Read(read => read.Action("Products_Read", "Home", new { categoryId = "#=CategoryID#" }))
                    )
                    .Pageable()
                    .ToClientTemplate()
            )
        </script>
    ```

12. Specify the `id` of the template using the `ClientDetailTemplateId` method.

    ```Razor HtmlHelper
        @(Html.Kendo().Grid<KendoGridClientHierarchy.Models.Category>()
              .Name("grid")
              .Columns(columns =>
              {
                  columns.Bound(category => category.CategoryID);
                  columns.Bound(category => category.CategoryName);
              })
              .DataSource(dataSource =>
                  dataSource.Ajax().Read(read => read.Action("Categories_Read", "Home"))
              )
              .ClientDetailTemplateId("client-template")
        )
    ```

13. Build and run the project.

    ![UI for ASP.NET MVC The final result is a hierarchical Grid](https://www.telerik.com/aspnet-mvc/documentation/assets/3bb95dc3f447579ad6424bdba9d8d9f0/grid-hierarchy.png)

To download the Visual Studio Project, refer to [this GitHub repository](https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Areas/GridHierarchyClientDetailTemplate).

## Handling Nested Client Templates

Nesting client templates are not an out-of-the-box feature the Kendo UI Core wrappers support. For more information on this issue, check the Grid troubleshooting section in [invalid template errors when nesting client templates](https://www.telerik.com/aspnet-mvc/documentation/html-helpers/data-management/grid/troubleshoot/known-exceptions#invalid-template-error-when-nesting-client-templates).

## See Also

* [Client Detail Templates by the Grid HtmlHelper for ASP.NET MVC (Demo)](https://demos.telerik.com/aspnet-mvc/grid/detailtemplate)
* [Server-Side API](https://www.telerik.com/aspnet-mvc/documentation/api/grid)
