Introduction
In this post, I am explain how to Populate Treeview Nodes Dynamically (On Demand) using in MVC 4 application.Steps :
Step - 1 : Create New Project.
Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Internet Application > Select view engine Razor > OKStep-2: Add a Database.
Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.Step-3: Create table for fetch data.
Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.Step-4: Add Entity Data Model.
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.
Step-5: Add a new Controller.
Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.Step-6: Add new action into your controller for Get Method
Here I have added "OnDemand" Action into "Treeview" Controller. Please write this following code public ActionResult OnDemand()
{
List<SiteMenu> all = new List<SiteMenu>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
all = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(0)).ToList();
}
return View(all);
}
Step-7:: Add another new action into your controller for Get Method for Get Sub Menu of selected menu.
Here I have added "GetSubMenu" Action into "Treeview" Controller. Please write this following code public JsonResult GetSubMenu(string pid)
{
// this action for Get Sub Menus from database and return as json data
System.Threading.Thread.Sleep(5000);
List<SiteMenu> subMenus = new List<SiteMenu>();
int pID = 0;
int.TryParse(pid, out pID);
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
subMenus = dc.SiteMenus.Where(a => a.ParentMenuID.Equals(pID)).OrderBy(a => a.MenuName).ToList();
}
return new JsonResult { Data= subMenus, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
Step-8: Add js file for get submenu and make this treeview collapsiable.
Go to Solution Explorer > Right Click on Script folder > ADD > New Item > Select Javascript file under Web > Enter File name > add. $(document).ready(function () {
$(".collapsible").live("click", function (e) {
e.preventDefault();
var this1 = $(this); // Get Click item
var data = {
pid: $(this).attr('pid')
};
var isLoaded = $(this1).attr('data-loaded'); // Check data already loaded or not
if (isLoaded == "false") {
$(this1).addClass("loadingP"); // Show loading panel
$(this1).removeClass("collapse");
// Now Load Data Here
$.ajax({
url: "/Treeview/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 {
// no sub menu
$(this1).css({'dispaly':'inline-block','width':'15px'});
}
$(this1).attr('data-loaded', true);
},
error: function () {
alert("Error!");
}
});
}
else {
// if already data loaded
$(this1).toggleClass("collapse expand");
$(this1).closest('li').children('ul').slideToggle();
}
});
});
Step-9: Add view for the Action (OnDemand) & design.
Right Click on Action Method (here right click on form action) > Add View... > Enter View Name > Select View Engine (Razor) > Check "Create a strong-typed view" > Select your model class > Add. [N:B:Please Rebuild solution before add view.]HTML Code
@model List<MVATreeviewOndemand.SiteMenu>
@{
ViewBag.Title = "OnDemand";
}
@* Here We will add some css for looks treeview good *@
<h2>OnDemand - Treeview</h2>
<div style="border:1px solid black; padding:0px; background-color:#FAFAFA">
@{
<div class="treeview">
@{
if (Model != null && Model.Count() > 0)
{
@*Here I will going 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>
</span>
</li>
}
</ul>
}
}
</div>
}
</div>
CSS Code
<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;
list-style: none;
}
.treeview > li > a {
font-weight: bold;
}
.treeview li a {
padding: 4px;
font-size: 12px;
display: inline-block;
text-decoration: none;
width: auto;
}
</style>
JS Code
@section Scripts{
@* Here I am going to add js code for populate submenu for the selected tree node *@
<script src="~/Scripts/MyTreeview.js"></script>
}
Complete View
@model List<MVATreeviewOndemand.SiteMenu>
@{
ViewBag.Title = "OnDemand";
}
@* Here We will add some css for looks treeview good *@
<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;
list-style: none;
}
.treeview > li > a {
font-weight: bold;
}
.treeview li a {
padding: 4px;
font-size: 12px;
display: inline-block;
text-decoration: none;
width: auto;
}
</style>
<h2>OnDemand - Treeview</h2>
<div style="border:1px solid black; padding:0px; background-color:#FAFAFA">
@{
<div class="treeview">
@{
if (Model != null && Model.Count() > 0)
{
@*Here I will going 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>
</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>
}
Step-10: Run Application.
Download Application Live Demo
