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. /* Sticky footer styles
  13. -------------------------------------------------- */
  14. html {
  15. position: relative;
  16. min-height: 100%;
  17. }
  18. body {
  19. /* Margin bottom by footer height */
  20. margin-bottom: 60px;
  21. }
  22. .footer {
  23. position: absolute;
  24. bottom: 0;
  25. width: 100%;
  26. /* Set the fixed height of the footer here */
  27. height: 60px;
  28. background-color: #f5f5f5;
  29. }
  30. .container-fluid .text-muted {
  31. margin: 20px 0;
  32. }
  33. .placeholders {
  34. margin: 30px auto;
  35. }
  36. .placeholder img {
  37. display: inline-block;
  38. }
  39. p .k-button {
  40. margin: 0 15px 0 0;
  41. }
  42. .btn-toggle {
  43. position: absolute;
  44. top: 0;
  45. left: 0;
  46. box-shadow: none;
  47. height: 48px;
  48. }
  49. .btn-toggle .k-icon {
  50. opacity: 1;
  51. }
  52. .btn-toggle,
  53. .k-primary.btn-toggle:hover,
  54. .btn-toggle:focus:active:not(.k-state-disabled):not([disabled]),
  55. .btn-toggle:focus:not(.k-state-disabled):not([disabled]) {
  56. box-shadow: none;
  57. border-radius: 0;
  58. }
  59. .btn-toggle .k-i-hbars,
  60. .k-primary.btn-toggle:hover .k-i-hbars,
  61. .btn-toggle:focus:active:not(.k-state-disabled):not([disabled]) .k-i-hbars,
  62. .btn-toggle:focus:not(.k-state-disabled):not([disabled]) .k-i-hbars {
  63. background-position: -80px -32px;
  64. }
  65. @@media (max-width: 768px) {
  66. .k-item {
  67. display: block;
  68. clear: both;
  69. float: none;
  70. width: 100%;
  71. }
  72. .k-header h1 {
  73. margin: 0;
  74. padding: 16px 15px 14px 60px;
  75. font-size: 18px;
  76. font-weight: lighter;
  77. }
  78. }
  79. </style>
  80. <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.common-material.min.css")" rel="stylesheet" type="text/css" />
  81. <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.mobile.all.min.css")" rel="stylesheet" type="text/css" />
  82. <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" />
  83. <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.material.min.css")" rel="stylesheet" type="text/css" />
  84. <link href="@Url.Content("~/Content/kendo/2016.2.504/kendo.dataviz.material.min.css")" rel="stylesheet" type="text/css" />
  85. <script src="@Url.Content("~/Scripts/kendo/2016.2.504/jquery.min.js")"></script>
  86. <script src="@Url.Content("~/Scripts/kendo/2016.2.504/angular.min.js")"></script>
  87. <script src="@Url.Content("~/Scripts/kendo/2016.2.504/jszip.min.js")"></script>
  88. <script src="@Url.Content("~/Scripts/kendo/2016.2.504/kendo.all.min.js")"></script>
  89. <script src="@Url.Content("~/Scripts/kendo/2016.2.504/kendo.aspnetmvc.min.js")"></script>
  90. </head>
  91. <body>
  92. <header>
  93. <div class="content-wrapper">
  94. <div class="float-left">
  95. <h2 class="site-title" style="margin-left: 30%;font-size: 1.2em !important;">www.CoderFunda.com</h2>
  96. </div>
  97. </div>
  98. </header>
  99. @RenderBody()
  100. <div class="container-fluid">
  101. <div class="row">
  102. </div>
  103. </div>
  104. <footer class="footer">
  105. <div class="container-fluid">
  106. <p class="text-muted">Copyright © 2002-2015 Telerik. All rights reserved.</p>
  107. </div>
  108. </footer>
  109. </body>
  110. </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 { get; set; }
  4. public int SrNo { get; set; }
  5. public string Name { get; set; }
  6. public int? ParentId { get; set; }
  7. public int ChildId { get; set; }
  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. private IEnumerable<Models.Product> TreeList()
  20. {
  21. List<Models.Product> objCmp = new List<Models.Product>();
  22. objCmp.Add(new Models.Product() { Id = 1, SrNo = 100, Name = "Pen", ParentId = null, ChildId = 1 });
  23. objCmp.Add(new Models.Product() { Id = 2, SrNo = 101, Name = "Ink Pen", ParentId = 1, ChildId = 2 });
  24. objCmp.Add(new Models.Product() { Id = 3, SrNo = 102, Name = "Jel Pen", ParentId = 1, ChildId = 3 });
  25. objCmp.Add(new Models.Product() { Id = 4, SrNo = 103, Name = "Marker Pen", ParentId = 1, ChildId = 4 });
  26. objCmp.Add(new Models.Product() { Id = 11, SrNo = 200, Name = "Books", ParentId = null, ChildId = 11 });
  27. objCmp.Add(new Models.Product() { Id = 12, SrNo = 201, Name = "Horror", ParentId = 11, ChildId = 12 });
  28. objCmp.Add(new Models.Product() { Id = 13, SrNo = 202, Name = "Satire", ParentId = 11, ChildId = 13 });
  29. objCmp.Add(new Models.Product() { Id = 14, SrNo = 203, Name = "Mystery", ParentId = 11, ChildId = 14 });
  30. IEnumerable<Models.Product> itemsResult = objCmp.ToList();
  31. return itemsResult.AsEnumerable();
  32. }
  33. }
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.