In this article, we are going to learn about implementing nested Kendo Grid, using angular js and Webapi in ASP.NET MVC 5 Web Application. In previous articles we learned about implementing CRUD operations in Kendo Grid using Angular js framework with WebAPI. If you are new to Web API, please refer previous posts.
Note: If you are not comfortable with Angular js, you can also implement Kendo Grid, using jQuery. Also please refer to Implementing CRUD operations on kendo grid using jquery. Angular Kendo Grid also internally uses jQuery for the data operations (retrieval, update, delete etc).
Now, let's discuss about our new tutorial Nested Kendo Grid implementation in this article.
Create a Basic Kendo grid using angular js
- Please refer to this previous post link to implement the basic Kendo Grid (Here, I am extending the previous sample Application).
- This is the screen shot of final nested Kendo Grid.
- I will explain the changes, I did, step by step.
Add another table to DB
- Here, I created another table "TDetails" to show the nested details for a grid row.
- Schema definition for TDetails are as follows-
- CREATE TABLE [dbo].[TDetails] (
- [DetailsID] INT IDENTITY (1, 1) NOT NULL,
- [CompanyName] VARCHAR (50) NOT NULL,
- [Salary] VARCHAR (50) NOT NULL,
- [Location] VARCHAR (50) NOT NULL,
- [StudentID] INT NULL,
- PRIMARY KEY CLUSTERED ([DetailsID] ASC)
- );
- Now, click StudentEntity.edmx file in Models folder. You will get an Entity diagram, as shown below-
- Click Update Model from the database and add the table, you recently created to StudentEntity.edmx.
- Here, I already added the Table.
Add a new method to api Controller
- Add the code, given below, to get JSON data for the nested grid.
- [HttpGet]
- [Route("StudentDetails/{id}")]
- public HttpResponseMessage GetStudentDetails(int id)
- {
- try
- {
- var studesription = db.TDetails.Where(a => a.StudentID.Equals(id)).ToList();
- return Request.CreateResponse(HttpStatusCode.OK, studesription, Configuration.Formatters.JsonFormatter);
-
- }
- catch (Exception ex)
- {
- return Request.CreateResponse(HttpStatusCode.OK, ex.Message, Configuration.Formatters.JsonFormatter);
- }
- }
- This method gets the data from API controller, based on StudentID. Add the extra code, given below, to view-
- Add the extra code, given below, to Index view to make Kendo nested-
- <!--Kendo ui elements-->
- <div id="example" ng-app="KendoGridDemo">
- <h3>CRUD operations on Kendo grid using Angualr JS & webapi</h3>
- <div ng-controller="Controller">
- <kendo-grid k-options="mainGridOptions">
- <!--nested grid template start-->
- <div k-detail-template>
- <div>
- <div kendo-grid k-options="subgridOptions(dataItem)">
- </div>
- </div>
- </div>
- <!--nested grid template end-->
- </kendo-grid>
- </div>
- </div>
- I added the nested grid template to the main grid. 5. Add the scripting code, given below, to populate the nested grid with the data.
-
- dataBound: function () {
- this.expandRow(this.tbody.find("tr.k-master-row").first());
- },
-
-
- $scope.subgridOptions = function (dataItem) {
- return {
- dataSource: {
- type: "json",
- transport: {
- read: {
- url: "http://localhost:13547/api/TStudentsAPI/StudentDetails/" + dataItem.StudentID,
- dataType:"json"
- }
- },
- serverPaging: true,
- serverSorting: true,
- serverFiltering: true,
- pageSize: 5,
- },
- scrollable: false,
- sortable: true,
- pageable: true,
- columns: [
- {
- field: "DetailsID",
- title: "DetailsID",
- width: "180px"
- },
- {
- field: "CompanyName",
- title: "Company Name",
- width: "180px"
- },
- {
- field: "Salary",
- title: "Salary",
- width: "180px"
- },
- {
- field: "Location",
- title: "Location",
- width: "180px"
- },
-
- ]
- };
- The complete Index view code after the changes are given below-
- <!--Kendo style reference files-->
- <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css" />
- <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.flat.min.css" />
- <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.mobile.min.css" />
-
- <!--kendo script reference files-->
- <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
- <script src="http://kendo.cdn.telerik.com/2016.1.412/js/angular.min.js"></script>
- <script src="http://kendo.cdn.telerik.com/2016.1.412/js/jszip.min.js"></script>
- <script src="http://kendo.cdn.telerik.com/2016.1.412/js/kendo.all.min.js"></script>
-
- <!--Kendo ui elements-->
- <div id="example" ng-app="KendoGridDemo">
- <h3>CRUD operations on Kendo grid using Angualr JS & webapi</h3>
- <div ng-controller="Controller">
- <kendo-grid k-options="mainGridOptions">
- <!--nested grid template start-->
- <div k-detail-template>
- <div>
- <div kendo-grid k-options="subgridOptions(dataItem)">
- </div>
- </div>
- </div>
- <!--nested grid template end-->
- </kendo-grid>
- </div>
- </div>
-
- <script>
-
- angular.module("KendoGridDemo", ["kendo.directives"])
- .controller("Controller", function ($scope) {
-
- $scope.mainGridOptions = {
- dataSource: {
- type: "json",
- transport: {
- destroy: {
- url: "api/TStudentsAPI",
- type: "DELETE"
- }, read: {
- url: "http://localhost:13547/api/TStudentsAPI",
- dataType: "json",
- },
- create:
- {
- url: "http://localhost:13547/api/TStudentsAPI",
- type: "POST"
- },
- update:
- {
- url: "api/TStudentsAPI",
- type: "PUT",
- parameterMap: function (options, operation) {
- if (operation !== "read" && options.models) {
- return {
- models: kendo.stringify(options.models)
- };
- }
- }
- },
- },
- schema:
- {
- model:
- {
- id: "StudentID",
- fields: {
- StudentID: { editable: false, nullable: false, type: "number" },
- FullName: { editable: true, nullable: true, type: "string" },
- Contact: { editable: true, nullable: true, type: "number" },
- Country: { editable: true, nullable: true, type: "string" },
- Designation: { editable: true, nullable: true, type: "string" }
- }
- }
- },
- pageSize: 5,
- serverPaging: true,
- serverSorting: true
- },
- editable: "popup",
- toolbar: ["create"],
- sortable: {
- mode: "single",
- allowUnsort:true
- },
- pageable: {
- buttonCount: 5
- },
- resizeable: true,
- scrollable: false,
- dataBound: function () {
- this.expandRow(this.tbody.find("tr.k-master-row").first());
- },
-
- columns: [{
- field: "StudentID",
- title: "Student ID",
- width: "180px"
- },
- {
- field: "FullName",
- title: "FullName",
- width: "180px"
- },
- {
- field: "Contact",
- title: "Contact",
- width: "180px"
- },
- {
- field: "Country",
- title: "Country",
- width: "180px"
- },
- {
- field: "Designation",
- title: "Designation",
- width: "180px"
- },
-
- {
- title:"Actions",
- command: ["edit",
- {
- name: "destroy",
- text: "Delete",
- width: "120px"
- }
- ],
- }
- ]
- };
- $scope.subgridOptions = function (dataItem) {
- return {
- dataSource: {
- type: "json",
- transport: {
- read: {
- url: "http://localhost:13547/api/TStudentsAPI/StudentDetails/" + dataItem.StudentID,
- dataType:"json"
- }
- },
- serverPaging: true,
- serverSorting: true,
- serverFiltering: true,
- pageSize: 5,
- },
- scrollable: false,
- sortable: true,
- pageable: true,
- columns: [
- {
- field: "DetailsID",
- title: "DetailsID",
- width: "180px"
- },
- {
- field: "CompanyName",
- title: "Company Name",
- width: "180px"
- },
- {
- field: "Salary",
- title: "Salary",
- width: "180px"
- },
- {
- field: "Location",
- title: "Location",
- width: "180px"
- },
-
- ]
- };
- };
- });
- </script>
- Now, run the Application and see the output in the Browser.
- Download the source code for this Application here Source Code(VS2015 code) .
Conclusion
I hope, this tutorial is understandable and useful for every reader. Please comment, if you have suggestions for any modification to improve the quality of an article. Please see this article in my blog Nested Kendo Grid.