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.
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,
- USE [SatyaDB]
- GO
- /****** Object: Table [dbo].[SiteMenu] Script Date: 02-10-2019 21:48:06 ******/
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- CREATE TABLE [dbo].[SiteMenu](
- [MenuID] [int] IDENTITY(1,1) NOT NULL,
- [MenuName] [varchar](100) NOT NULL,
- [NavURL] [varchar](200) NOT NULL,
- [ParentMenuID] [int] NOT NULL,
- CONSTRAINT [PK_SiteMenu] PRIMARY KEY CLUSTERED
- (
- [MenuID] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
- SET IDENTITY_INSERT [dbo].[SiteMenu] ON
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (1, N'MyIndex', N'#', 0)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (3, N'Home', N'/Home/Index', 1)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (5, N'About', N'/Home/About', 1)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (8, N'Contact', N'/Home/Contact', 1)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (9, N'MyBlog', N'#', 0)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (10, N'CsharpCorner', N'/Home/CsharpCorner', 9)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (11, N'DotNetTricks', N'/Home/DotNetTricks', 9)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (12, N'DZone', N'/Home/Dzone', 9)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (13, N'Microsoft', N'/Home/Microsoft', 9)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (14, N'Technetwiki', N'/Home/Technetwiki', 13)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (15, N'MSDN', N'/Home/MSDN', 13)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (16, N'Google', N'/Home/Google', 9)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (17, N'Youtube', N'/Home/Youtube', 16)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (18, N'Blogger', N'/Home/Blogger', 16)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (19, N'MySocialSite', N'#', 0)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (20, N'Facebook', N'/Home/Facebook', 19)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (22, N'Gmail', N'/Home/Gmail', 19)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (23, N'Twitter', N'/Home/Twitter', 19)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (24, N'Outlook', N'/Home/Outlook', 19)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (25, N'Awards', N'#', 0)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (26, N'C# Corner', N'/Home/CC', 25)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (27, N'DZone', N'/Home/DZ', 25)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (28, N'DotNetTricks', N'/Home/DNT', 25)
- GO
- INSERT [dbo].[SiteMenu] ([MenuID], [MenuName], [NavURL], [ParentMenuID]) VALUES (29, N'Bootstrap Book', N'/Home/Book', 28)
- GO
- SET IDENTITY_INSERT [dbo].[SiteMenu] OFF
- GO
Step 2
Add a controller action method named TreeView in HomeController.cs file for get method.
Code Ref
- public ActionResult TreeView()
- {
- List<SiteMenu> all = new List<SiteMenu>();
- using (SatyaDBEntities dc = new SatyaDBEntities())
- {
- all = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(0)).ToList();
- }
-
- return View(all);
- }
Code Description
Here we can show the parent menu from the database. SiteMenus is the entity set name where parent menu retrieves from backend.
- 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
- public JsonResult GetSubMenu(string pid) {
- System.Threading.Thread.Sleep(5000);
- List < SiteMenu > subMenus = new List < SiteMenu > ();
- int pID = 0;
- int.TryParse(pid, out pID);
- using(SatyaDBEntities dc = new SatyaDBEntities()) {
- subMenus = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(pID)).OrderBy(a => a.MenuName).ToList();
- }
-
- return new JsonResult {
- Data = subMenus, JsonRequestBehavior = JsonRequestBehavior.AllowGet
- };
- }
Code Description
The below line of code sets to get Sub Menus from database and return as json data.
- using(SatyaDBEntities dc = new SatyaDBEntities()) {
- subMenus = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(pID)).OrderBy(a => a.MenuName).ToList();
- }
-
- return new JsonResult {
- Data = subMenus, JsonRequestBehavior = JsonRequestBehavior.AllowGet
- };
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
- $(document).ready(function () {
-
- $(".collapsible").live("click", function (e) {
- e.preventDefault();
-
- var this1 = $(this);
- var data = {
- pid: $(this).attr('pid')
- };
-
- var isLoaded = $(this1).attr('data-loaded');
- if (isLoaded == "false") {
- $(this1).addClass("loadingP");
- $(this1).removeClass("collapse");
-
-
- $.ajax({
- url: "/Home/GetSubMenu",
- type: "GET",
- data: data,
- dataType: "json",
- success: function (d) {
- $(this1).removeClass("loadingP");
-
- if (d.length > 0) {
-
- var $ul = $("<ul></ul>");
- $.each(d, function (i, ele) {
- $ul.append(
- $("<li></li>").append(
- "<span class='collapse collapsible' data-loaded='false' pid='" + ele.MenuID + "'> </span>" +
- "<span><a href='" + ele.NavURL + "'>" + ele.MenuName + "</a></span>"
- )
- )
- });
-
- $(this1).parent().append($ul);
- $(this1).addClass('collapse');
- $(this1).toggleClass('collapse expand');
- $(this1).closest('li').children('ul').slideDown();
- }
- else {
-
- $(this1).css({ 'dispaly': 'inline-block', 'width': '15px' });
- }
-
- $(this1).attr('data-loaded', true);
- },
- error: function () {
- bootbox.alert("There Is Some Error. So, The Request Can't Be Processed Now!");
- }
- });
- }
- else {
-
- $(this1).toggleClass("collapse expand");
- $(this1).closest('li').children('ul').slideToggle();
- }
-
- });
- });
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
- @model List<MVCModalApp.SiteMenu>
-
- @*Bootbox alert ref*@
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">
- </script>
-
- @* Here We will add some css for looks treeview good *@
- @*.loadingP for showing loading panel
- .collapse for showing icon with every parent menu
- .expand for showing icon with every sub menu
- .treeview for adding style to menu and submenu like color and font size etc.*@
-
- <style>
- .loadingP {
- background-image: url('../Images/generated-image.gif');
- width: 15px;
- display: inline-block;
- }
-
- .collapse {
- width: 15px;
- background-image: url('../Images/ui-icons_454545_256x240.png');
- background-repeat: no-repeat;
- background-position: -36px -17px;
- display: inline-block;
- cursor: pointer;
- }
-
- .expand {
- width: 15px;
- background-image: url('../Images/ui-icons_454545_256x240.png');
- background-repeat: no-repeat;
- background-position: -50px -17px;
- display: inline-block;
- cursor: pointer;
- }
-
- .treeview ul {
- font: 14px Arial, Sans-Serif;
- margin: 0px;
- padding-left: 20px;
- font-weight: bold;
- color: blue;
- list-style: none;
- }
-
- .treeview > li > a {
- font-weight: bold;
- }
-
- .treeview li a {
- padding: 4px;
- font-size: 16px;
- display: inline-block;
- font-weight: bold;
- color: blue;
- text-decoration: none;
- width: auto;
- }
- </style>
-
- <h2 style="background-color: darkorange;color: white; text-align: center; font-style: oblique">Treeview Control Using MVC</h2>
- <br />
- <div style="border:4px solid blue; padding:0px; background-color:yellow">
- @{
- <div class="treeview">
- @{
- if (Model != null && Model.Count() > 0)
- {
- @*Here I will show steps to load Treeview menus*@
- <ul>
- @foreach (var i in Model)
- {
- <li>
- <span class="collapse collapsible" data-loaded="false" pid="@i.MenuID"> </span>
- @* Here I have added the above span for collapsible button for treeview *@
- @* and data-loaded="false" means its sub menu not loaded yet from database *@
- <span>
- <a href="@i.NavURL">@i.MenuName</a> @*navigate to url for related menu*@
- </span>
- </li>
- }
- </ul>
- }
- }
- </div>
- }
- </div>
-
- @section Scripts{
- @* Here I am going to add js code for populate submenu for the selected tree node *@
- <script src="~/Scripts/MyTreeview.js"></script>
- }
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