Kendo TreeList Moving A Node Up And Down In ASP.NET MVC Using JavaScript

Introduction

In this article, you will learn how to move a node up and down in Kendo TreeList in ASP.NET MVC, using JavaScript. Many times, while working with TreeList, we need to move a node up & down in ASP.NET MVC.

If you are going to display any tree on GUI, then you can use TreeView and TreeList. Generally, it is a tree structure with parent & child relationship.

The basic structure which you'll need to implement any tree will be a collection of nodes. If you need to only navigate down the tree, then a First Node needs a List of children. If you need to navigate up the tree, then the last node needs a link to its parent node.
 
Step 1

Create a new MVC Empty Project, using Visual Studio.

Add new Layout.cshtml into the shared folder. Add references of Kendo, CSS and JavaScript into this Layout.cshtml. 
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <title>@ViewBag.Title - My Telerik MVC Application</title>  
  5.     <style>  
  6.             .k-header h1 {  
  7.                 margin: 0;  
  8.                 padding: 30px 15px;  
  9.                 font-size: 32px;  
  10.                 font-weight: lighter;  
  11.             }  
  12.   
  13.             /* Sticky footer styles  
  14.         -------------------------------------------------- */  
  15.             html {  
  16.                 position: relative;  
  17.                 min-height: 100%;  
  18.             }  
  19.   
  20.             body {  
  21.                 /* Margin bottom by footer height */  
  22.                 margin-bottom: 60px;  
  23.             }  
  24.   
  25.             .footer {  
  26.                 position: absolute;  
  27.                 bottom: 0;  
  28.                 width: 100%;  
  29.                 /* Set the fixed height of the footer here */  
  30.                 height: 60px;  
  31.                 background-color: #f5f5f5;  
  32.             }  
  33.   
  34.             .container-fluid .text-muted {  
  35.                 margin: 20px 0;  
  36.             }  
  37.   
  38.             .placeholders {  
  39.                 margin: 30px auto;  
  40.             }  
  41.   
  42.             .placeholder img {  
  43.                 display: inline-block;  
  44.             }  
  45.   
  46.             p .k-button {  
  47.                 margin: 0 15px 0 0;  
  48.             }  
  49.   
  50.             .btn-toggle {  
  51.                 position: absolute;  
  52.                 top: 0;  
  53.                 left: 0;  
  54.                 box-shadow: none;  
  55.                 height: 48px;  
  56.             }  
  57.   
  58.                 .btn-toggle .k-icon {  
  59.                     opacity: 1;  
  60.                 }  
  61.   
  62.                 .btn-toggle,  
  63.                 .k-primary.btn-toggle:hover,  
  64.                 .btn-toggle:focus:active:not(.k-state-disabled):not([disabled]),  
  65.                 .btn-toggle:focus:not(.k-state-disabled):not([disabled]) {  
  66.                     box-shadow: none;  
  67.                     border-radius: 0;  
  68.                 }  
  69.   
  70.                     .btn-toggle .k-i-hbars,  
  71.                     .k-primary.btn-toggle:hover .k-i-hbars,  
  72.                     .btn-toggle:focus:active:not(.k-state-disabled):not([disabled]) .k-i-hbars,  
  73.                     .btn-toggle:focus:not(.k-state-disabled):not([disabled]) .k-i-hbars {  
  74.                         background-position: -80px -32px;  
  75.                     }  
  76.   
  77.             @@media (max-width: 768px) {  
  78.                 .k-item {  
  79.                     display: block;  
  80.                     clear: both;  
  81.                     float: none;  
  82.                     width: 100%;  
  83.                 }  
  84.   
  85.                 .k-header h1 {  
  86.                     margin: 0;  
  87.                     padding: 16px 15px 14px 60px;  
  88.                     font-size: 18px;  
  89.                     font-weight: lighter;  
  90.                 }  
  91.             }  
  92.     </style>  
  93.     <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.common-material.min.css")" rel="stylesheet" type="text/css" />  
  94.     <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.mobile.all.min.css")" rel="stylesheet" type="text/css" />  
  95.     <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" />  
  96.     <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.material.min.css")" rel="stylesheet" type="text/css" />  
  97.     <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.dataviz.material.min.css")" rel="stylesheet" type="text/css" />  
  98.     <script src="@Url.Content("~/Scripts/kendo/2016.2.504/jquery.min.js")"></script>  
  99.     <script src="@Url.Content("~/Scripts/kendo/2016.2.504/angular.min.js")"></script>  
  100.     <script src="@Url.Content("~/Scripts/kendo/2016.2.504/jszip.min.js")"></script>  
  101.     <script src="@Url.Content("~/Scripts/kendo/2016.2.504/kendo.all.min.js")"></script>  
  102.     <script src="@Url.Content("~/Scripts/kendo/2016.2.504/kendo.aspnetmvc.min.js")"></script>  
  103. </head>  
  104. <body>  
  105.     <header>  
  106.         <div class="content-wrapper">  
  107.             <div class="float-left">  
  108.                 <h2 class="site-title" style="margin-left: 30%;font-size: 1.2em !important;">www.CoderFunda.com</h2>  
  109.             </div>  
  110.         </div>  
  111.     </header>  
  112.     @RenderBody()  
  113.     <div class="container-fluid">  
  114.         <div class="row">  
  115.   
  116.         </div>  
  117.     </div>  
  118.     <footer class="footer">  
  119.         <div class="container-fluid">  
  120.             <p class="text-muted">Copyright © 2002-2015 Telerik. All rights reserved.</p>  
  121.         </div>  
  122.     </footer>  
  123. </body>  
  124. </html>  
Step 2

Now, add one model into a Model folder & give the name as Product. Add some properties into it.
  1. public class Product  
  2.  {  
  3.      public int Id { getset; }  
  4.      public int SrNo { getset; }  
  5.      public string Name { getset; }  
  6.      public int? ParentId { getset; }  
  7.      public int ChildId { getset; }  
  8.  }  
Add HomeController in Controller. There are two action methods; where the first will be adding a some dummy data to our properties & returns an IEnumerable result. Second one is used to bind the data into a tree structure format, using parent child relationship. 
  1. public class HomeController : Controller  
  2.     {  
  3.         public HomeController()  
  4.         {}  
  5.         public ActionResult Index()  
  6.         {  
  7.             return View();  
  8.         }  
  9.         public JsonResult GetTree([DataSourceRequest] DataSourceRequest request)  
  10.         {  
  11.             var result = TreeList()  
  12.                 .ToTreeDataSourceResult(request,  
  13.                 e => e.ChildId,  
  14.                 e => e.ParentId,  
  15.                 e => e  
  16.             );  
  17.             return Json(result, JsonRequestBehavior.AllowGet);  
  18.         }  
  19.   
  20.         private IEnumerable<Models.Product> TreeList()  
  21.         {  
  22.             List<Models.Product> objCmp = new List<Models.Product>();  
  23.             objCmp.Add(new Models.Product() { Id = 1, SrNo = 100, Name = "Pen", ParentId = null, ChildId = 1 });  
  24.             objCmp.Add(new Models.Product() { Id = 2, SrNo = 101, Name = "Ink Pen", ParentId = 1, ChildId = 2 });  
  25.             objCmp.Add(new Models.Product() { Id = 3, SrNo = 102, Name = "Jel Pen", ParentId = 1, ChildId = 3 });  
  26.             objCmp.Add(new Models.Product() { Id = 4, SrNo = 103, Name = "Marker Pen", ParentId = 1, ChildId = 4 });  
  27.   
  28.             objCmp.Add(new Models.Product() { Id = 11, SrNo = 200, Name = "Books", ParentId = null, ChildId = 11 });  
  29.             objCmp.Add(new Models.Product() { Id = 12, SrNo = 201, Name = "Horror", ParentId = 11, ChildId = 12 });  
  30.             objCmp.Add(new Models.Product() { Id = 13, SrNo = 202, Name = "Satire", ParentId = 11, ChildId = 13 });  
  31.             objCmp.Add(new Models.Product() { Id = 14, SrNo = 203, Name = "Mystery", ParentId = 11, ChildId = 14 });  
  32.   
  33.             IEnumerable<Models.Product> itemsResult = objCmp.ToList();  
  34.             return itemsResult.AsEnumerable();  
  35.         }  
  36.     }  
Step 3

Add View by right clicking on Action Method Index, which will show a tree list with the hierarchy. This tree contains a read method from which we are binding the records to treelist. Also, take two buttons, where first is to move a tree node in up & another one to move a tree node down. I have added some custome css for better look & feel of headers of treelist. Now, add a JavaScript code into a document.ready function. For onclick button, I am going to write the code, which will move the record up & down.
  1. @using System.Web.Optimization  
  2. @using Kendo.Mvc.UI  
  3. @using Kendo.Mvc.Extensions  
  4. @{  
  5.     Layout = "~/Views/Shared/_Layout.cshtml";  
  6. }  
  7. <style type="text/css">  
  8.     .myCSS {  
  9.         font-weight: 800 !important;  
  10.         text-align: center !important;  
  11.         background-color: #F1E1AE !important;  
  12.         border-color: #ffffff;  
  13.         border-style: solid;  
  14.         border-width: thin;  
  15.     }  
  16. </style>  
  17. <br />  
  18. <br />  
  19. <div class="col-xs-12">  
  20.     <div class="row">  
  21.         <div class="col-xs-6" style="height:450px; width:60%; margin-left:5%">  
  22.             @(Html.Kendo().TreeList<TreeList.Models.Product>()  
  23.                                  .Name("ProductTreeList")  
  24.                                  .Columns(columns =>  
  25.                                  {  
  26.                                      columns.Add().Field(e => e.SrNo).Title("Sr. No.").Width(10).HeaderAttributes(new { @class = "myCSS" });  
  27.                                      columns.Add().Field(e => e.Name).Width(20).HeaderAttributes(new { @class = "myCSS" });  
  28.                                      columns.Add().Field(e => e.ParentId).Hidden(true).Width(5);  
  29.                                      columns.Add().Field(e => e.ChildId).Hidden(true).Width(5);  
  30.                                  })  
  31.                                 .DataSource(dataSource => dataSource  
  32.                                 .Read(read => read.Action("GetTree", "Home"))  
  33.                                 .ServerOperation(false)  
  34.                                 .Model(m =>  
  35.                                 {  
  36.                                     m.Id(f => f.ChildId);  
  37.                                     m.ParentId(f => f.ParentId);  
  38.                                     m.Expanded(true);  
  39.                                     m.Field(f => f.SrNo);  
  40.                                 })  
  41.                                 )  
  42.                                 .Selectable(true)  
  43.                                 .Height(480)  
  44.             )  
  45.         </div>  
  46.         <div align="right" class="col-xs-2" style="margin-right:20%;">  
  47.             <div>  
  48.                 <button id="btnUp" type="button" class="btn btn-primary" style="line-height:1.0;">Move Up</button>  
  49.             </div>  
  50.         </div>  
  51.         <br />  
  52.         <div align="right" class="col-xs-2" style="margin-right:20%;">  
  53.             <div>  
  54.                 <button id="btnDown" type="button" class="btn btn-primary" style="line-height:1.0;">Move Down</button>  
  55.             </div>  
  56.         </div>  
  57.     </div>  
  58. </div>  
  59. <script>  
  60.     $(document).ready(function () {  
  61.         var myProductList = $("#ProductTreeList").data("kendoTreeList");  
  62.         $('#btnUp').click(function (e) {  
  63.             var rowIndex = myProductList.dataItem(myProductList.select());  
  64.             var selectedSrNo = rowIndex.SrNo;  
  65.             var data = myProductList.dataSource.data();  
  66.             for (var i = 0; i < data.length; i++) {  
  67.                 var currentDataItem = data[i];  
  68.                 var currentSrNo = currentDataItem.get("SrNo");  
  69.                 var currentName = currentDataItem.get("Name");  
  70.                 var currentChildId = currentDataItem.get("ChildId");  
  71.                 var oldName;  
  72.                 var oldChildId;  
  73.                 if (currentSrNo == (selectedSrNo - 1)) {  
  74.                     oldName = currentName;  
  75.                     oldChildId = currentChildId;  
  76.                 }  
  77.                 if (currentSrNo == selectedSrNo) {  
  78.                     data[i].set("SrNo", (selectedSrNo - 1));  
  79.                     data[i].set("Name", oldName);  
  80.                     data[i].set("ChildId", oldChildId);  
  81.                     data[i -1].set("SrNo", (selectedSrNo));  
  82.                     data[i - 1].set("Name", currentName);  
  83.                     data[i - 1].set("ChildId", currentChildId);  
  84.                 }  
  85.             }  
  86.         });  
  87.         $('#btnDown').click(function (e) {  
  88.             var rowIndex = myProductList.dataItem(myProductList.select());  
  89.             var selectedSrNo = rowIndex.SrNo;  
  90.             var data = myProductList.dataSource.data();  
  91.             for (var i = 0; i < data.length; i++) {  
  92.                 var currentDataItem = data[i];  
  93.                 var currentSrNo = currentDataItem.get("SrNo");  
  94.                 var currentName = currentDataItem.get("Name");  
  95.                 var currentChildId = currentDataItem.get("ChildId");  
  96.                 if (currentSrNo == (selectedSrNo)) {  
  97.                     data[i].set("SrNo", (data[i + 1].get("SrNo")));  
  98.                     data[i].set("Name", (data[i + 1].get("Name")));  
  99.                     data[i].set("ChildId", (data[i + 1].get("ChildId")));  
  100.                     data[i + 1].set("SrNo", (selectedSrNo));  
  101.                     data[i + 1].set("Name", currentName);  
  102.                     data[i + 1].set("ChildId", currentChildId);  
  103.                     return;  
  104.                 }  
  105.             }  
  106.         });  
  107.     });  
  108. </script>  
Step 4

Now, run the Application. First, select the node, which you want to move up or down.

If we select record 'Jel Pen' with Sr. No 102 & click Move up, then we will get the result, as shown below.


 

If we select record 'Horror' with Sr. No. 201 & click Move down, then we will get the result, as shown below.



 

Important
  • This treelist has only 2 levels i.e. parent nodes and children nodes.
  • For simplicity, this example uses some dummy data.
  • This example may not be covered in all real-world scenarios.
  • Please note that this is a custom implementation. Feel free to modify the implementation, as per your preferences.
Summary

In this article, you learned the basics of how to move a Kendo TreeList node up and down in ASP.NET MVC, using JavaScript.