Steps To Add 🔌 Treenodes Dynamically To Treeview Control Using MVC And Entity Framework

Here we learn how to display treeview menu and submenu using MVC and Entity Framework dynamically.

Introduction

 
In this article, we will learn step by step process to fetch treeview menu and submenu from database using MVC and Entity Framework. Also, We can learn how to set menu and submenu relationships between columns in table.
 
Prerequisites
  • Sql Server
  • Visual Studio
Note
 
Before going through this session, please visit my previous articles related to MVC and Entity Framework.
Step 1
 
First we need to create a table named "SiteMenu". Check the script as shown below including data,
  1. USE [SatyaDB]  
  2. GO  
  3. /****** Object:  Table [dbo].[SiteMenu]    Script Date: 02-10-2019 21:48:06 ******/  
  4. SET ANSI_NULLS ON  
  5. GO  
  6. SET QUOTED_IDENTIFIER ON  
  7. GO  
  8. CREATE TABLE [dbo].[SiteMenu](  
  9.     [MenuID] [int] IDENTITY(1,1) NOT NULL,  
  10.     [MenuName] [varchar](100) NOT NULL,  
  11.     [NavURL] [varchar](200) NOT NULL,  
  12.     [ParentMenuID] [intNOT NULL,  
  13.  CONSTRAINT [PK_SiteMenu] PRIMARY KEY CLUSTERED   
  14. (  
  15.     [MenuID] ASC  
  16. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  17. ON [PRIMARY]  
  18. GO  
  19. SET IDENTITY_INSERT [dbo].[SiteMenu] ON   
  20. GO  
  21. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (1, N'MyIndex', N'#', 0)  
  22. GO  
  23. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (3, N'Home', N'/Home/Index', 1)  
  24. GO  
  25. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (5, N'About', N'/Home/About', 1)  
  26. GO  
  27. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (8, N'Contact', N'/Home/Contact', 1)  
  28. GO  
  29. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (9, N'MyBlog', N'#', 0)  
  30. GO  
  31. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (10, N'CsharpCorner', N'/Home/CsharpCorner', 9)  
  32. GO  
  33. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (11, N'DotNetTricks', N'/Home/DotNetTricks', 9)  
  34. GO  
  35. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (12, N'DZone', N'/Home/Dzone', 9)  
  36. GO  
  37. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (13, N'Microsoft', N'/Home/Microsoft', 9)  
  38. GO  
  39. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (14, N'Technetwiki', N'/Home/Technetwiki', 13)  
  40. GO  
  41. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (15, N'MSDN', N'/Home/MSDN', 13)  
  42. GO  
  43. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (16, N'Google', N'/Home/Google', 9)  
  44. GO  
  45. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (17, N'Youtube', N'/Home/Youtube', 16)  
  46. GO  
  47. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (18, N'Blogger', N'/Home/Blogger', 16)  
  48. GO  
  49. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (19, N'MySocialSite', N'#', 0)  
  50. GO  
  51. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (20, N'Facebook', N'/Home/Facebook', 19)  
  52. GO  
  53. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (22, N'Gmail', N'/Home/Gmail', 19)  
  54. GO  
  55. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (23, N'Twitter', N'/Home/Twitter', 19)  
  56. GO  
  57. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (24, N'Outlook', N'/Home/Outlook', 19)  
  58. GO  
  59. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (25, N'Awards', N'#', 0)  
  60. GO  
  61. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (26, N'C# Corner', N'/Home/CC', 25)  
  62. GO  
  63. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (27, N'DZone', N'/Home/DZ', 25)  
  64. GO  
  65. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (28, N'DotNetTricks', N'/Home/DNT', 25)  
  66. GO  
  67. INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (29, N'Bootstrap Book', N'/Home/Book', 28)  
  68. GO  
  69. SET IDENTITY_INSERT [dbo].[SiteMenu] OFF  
  70. GO  
Step 2
 
Add a controller action method named TreeView in HomeController.cs file for get method.
 
Code Ref
  1. public ActionResult TreeView()  
  2.         {  
  3.             List<SiteMenu> all = new List<SiteMenu>();  
  4.             using (SatyaDBEntities dc = new SatyaDBEntities())  
  5.             {  
  6.                 all = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(0)).ToList();  
  7.             }  
  8.   
  9.             return View(all);  
  10.         }  
Code Description
 
Here we can show the parent menu from the database. SiteMenus is the entity set name where parent menu retrieves from backend.
  1. all = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(0)).ToList();  
Step 3
 
Here I added another new controller action method named GetSubMenu for get Method for getting Sub Menu of selected menu.
 
Code Ref
  1. public JsonResult GetSubMenu(string pid) {  
  2.  System.Threading.Thread.Sleep(5000);  
  3.  List < SiteMenu > subMenus = new List < SiteMenu > ();  
  4.  int pID = 0;  
  5.  int.TryParse(pid, out pID);  
  6.  using(SatyaDBEntities dc = new SatyaDBEntities()) {  
  7.   subMenus = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(pID)).OrderBy(a => a.MenuName).ToList();  
  8.  }  
  9.   
  10.  return new JsonResult {  
  11.   Data = subMenus, JsonRequestBehavior = JsonRequestBehavior.AllowGet  
  12.  };  
  13. } 
Code Description
 
The below line of code sets to get Sub Menus from database and return as json data.
  1. using(SatyaDBEntities dc = new SatyaDBEntities()) {  
  2.  subMenus = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(pID)).OrderBy(a => a.MenuName).ToList();  
  3. }  
  4.   
  5. return new JsonResult {  
  6.  Data = subMenus, JsonRequestBehavior = JsonRequestBehavior.AllowGet  
  7. }; 
Step 4
 
Here I added js file named "MyTreeview.js" for getting submenu and we can expand and collapse treeview menu and submenu.
 
Code Ref 
  1. $(document).ready(function () {  
  2.   
  3.     $(".collapsible").live("click"function (e) { //every parentmenu on click  
  4.         e.preventDefault();  
  5.   
  6.         var this1 = $(this); // Get Click item   
  7.         var data = {  
  8.             pid: $(this).attr('pid')  
  9.         };  
  10.   
  11.         var isLoaded = $(this1).attr('data-loaded'); // Check data already loaded or not  
  12.         if (isLoaded == "false") {  
  13.             $(this1).addClass("loadingP");   // Show loading panel at the time of click on parent menu  
  14.             $(this1).removeClass("collapse");  
  15.   
  16.             // Now Load Data Here   
  17.             $.ajax({  
  18.                 url: "/Home/GetSubMenu"//controller action method for getting submenu  
  19.                 type: "GET",  
  20.                 data: data,  
  21.                 dataType: "json"//return submenu as json data  
  22.                 success: function (d) {  
  23.                     $(this1).removeClass("loadingP"); //if submenu is displayed then loader will be hidden.  
  24.   
  25.                     if (d.length > 0) {  
  26.   
  27.                         var $ul = $("<ul></ul>");  
  28.                         $.each(d, function (i, ele) {  
  29.                             $ul.append(  
  30.                                 $("<li></li>").append( //Here submenu and the url associate with that submenu.  
  31.                                     "<span class='collapse collapsible' data-loaded='false' pid='" + ele.MenuID + "'> </span>" +  
  32.                                     "<span><a href='" + ele.NavURL + "'>" + ele.MenuName + "</a></span>"  
  33.                                 )  
  34.                             )  
  35.                         });  
  36.   
  37.                         $(this1).parent().append($ul);  
  38.                         $(this1).addClass('collapse');  
  39.                         $(this1).toggleClass('collapse expand'); //added collapse and expand css class  
  40.                         $(this1).closest('li').children('ul').slideDown();  
  41.                     }  
  42.                     else {  
  43.                         // no sub menu  
  44.                         $(this1).css({ 'dispaly''inline-block''width''15px' });  
  45.                     }  
  46.   
  47.                     $(this1).attr('data-loaded'true);  
  48.                 },  
  49.                 error: function () { // if any issue happens during fetching of records.  
  50.                     bootbox.alert("There Is Some Error. So, The Request Can't Be Processed Now!");  
  51.                 }  
  52.             });  
  53.         }  
  54.         else {  
  55.             // if already data loaded  
  56.             $(this1).toggleClass("collapse expand");  
  57.             $(this1).closest('li').children('ul').slideToggle();  
  58.         }  
  59.   
  60.     });  
  61. });  
Code Description
 
Here I added code with description in green comment mark "//" at one place for better and faster understanding.
 
Step 5
 
Here I added view/cshtml file for the TreeView action method to show UI design about treeview menu and submenu with other features.
 
Code Ref 
  1. @model List<MVCModalApp.SiteMenu>  
  2.   
  3. @*Bootbox alert ref*@  
  4. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  5. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
  6. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  7. <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
  8. </script>  
  9.   
  10. @* Here We will add some css for looks treeview good *@  
  11. @*.loadingP for showing loading panel  
  12. .collapse for showing icon with every parent menu  
  13. .expand for showing icon with every sub menu  
  14. .treeview for adding style to menu and submenu like color and font size etc.*@  
  15.    
  16. <style>  
  17.     .loadingP {  
  18.         background-image: url('../Images/generated-image.gif');  
  19.         width: 15px;  
  20.         display: inline-block;  
  21.     }  
  22.   
  23.     .collapse {  
  24.         width: 15px;  
  25.         background-image: url('../Images/ui-icons_454545_256x240.png');  
  26.         background-repeat: no-repeat;  
  27.         background-position: -36px -17px;  
  28.         display: inline-block;  
  29.         cursor: pointer;  
  30.     }  
  31.   
  32.     .expand {  
  33.         width: 15px;  
  34.         background-image: url('../Images/ui-icons_454545_256x240.png');  
  35.         background-repeat: no-repeat;  
  36.         background-position: -50px -17px;  
  37.         display: inline-block;  
  38.         cursor: pointer;  
  39.     }  
  40.   
  41.     .treeview ul {  
  42.         font: 14px Arial, Sans-Serif;  
  43.         margin: 0px;  
  44.         padding-left: 20px;  
  45.         font-weight: bold;  
  46.         color: blue;  
  47.         list-style: none;  
  48.     }  
  49.   
  50.     .treeview > li > a {  
  51.         font-weight: bold;  
  52.     }  
  53.   
  54.     .treeview li a {  
  55.         padding: 4px;  
  56.         font-size: 16px;  
  57.         display: inline-block;  
  58.         font-weight: bold;  
  59.         color: blue;  
  60.         text-decoration: none;  
  61.         width: auto;  
  62.     }  
  63. </style>  
  64.   
  65. <h2 style="background-color: darkorange;color: white; text-align: center; font-style: oblique">Treeview Control Using MVC</h2>  
  66. <br />  
  67. <div style="border:4px solid blue; padding:0px;  background-color:yellow">  
  68.     @{  
  69.         <div class="treeview">  
  70.             @{  
  71.                 if (Model != null && Model.Count() > 0)  
  72.                 {  
  73.                     @*Here I will show steps to load Treeview menus*@  
  74.                     <ul>  
  75.                         @foreach (var i in Model)  
  76.                         {  
  77.                             <li>  
  78.                                 <span class="collapse collapsible" data-loaded="false" pid="@i.MenuID"> </span>  
  79.                                 @* Here I have added the above span for collapsible button for treeview *@  
  80.                                 @* and data-loaded="false" means its sub menu not loaded yet from database *@  
  81.                                 <span>  
  82.                                     <a href="@i.NavURL">@i.MenuName</a> @*navigate to url for related menu*@  
  83.                                 </span>  
  84.                             </li>  
  85.                         }  
  86.                     </ul>  
  87.                 }  
  88.             }  
  89.         </div>  
  90.     }  
  91. </div>  
  92.   
  93. @section Scripts{  
  94.     @* Here I am going to add js code for populate submenu for the selected tree node *@  
  95.     <script src="~/Scripts/MyTreeview.js"></script>  
  96. }  
Code Description
 
Here I added code with description in green comment mark "@**@" at one place for better and faster understanding. 
 

OUTPUT

 
This shows for parent menu in treeview.
 
This shows for submenu in treeview. 
 
 
This shows for loading panel during access of submenu in treeview.
 
 
This shows for error alert message if any issue found during access of menu and submenu in treeview.
 
 
Link To Source Code, 

Summary


In this article, we have learned,
  • Treeview menu and submenu using MVC
  • Configure menu and submenu using the JavaScript file
  • Loading panel during access of menu and submenu
  • Error alert message if any issue found