One of the frequently used control is Tree view and Microsoft doesn’t have this in the default set of controls. We have to depend on the third party/JQuery controls. One of the free control is aciTree and can be download from Nuget. aciTree is a customizable JavaScript tree view control written as a jQuery plugin. It offers an easy to use API and it has built-in functionality to load the entire tree with AJAX.
How to use aciTree in MVC
1. Add the reference to set of aciTree JavaScript and CSS file
a. aciTree.css
b. jquery.min.js version should be >= 1.11.1
c. jquery.aciPlugin.min.js
d. jquery.aciTree.dom.js
e. jquery.aciTree.core.js (Optional)
f. jquery.aciTree.selectable.js (Optional)
g. jquery.aciTree.checkbox.js
h. jquery.aciTree.radio.js
i. jquery.aciTree.min.js
2. Declare the search box if search functionality is required
Search: <input id=”search” type=”text” value=”” name=”search”>
3. Declare div with id and CSS classes
<div id=”tree” class=”aciTree”></div>
4. Call the WEB-API method for data and it should be return in JSON format
$(‘#tree’).aciTree({
ajax: {
//Calling controller method
url: ‘/Home/GetTreeView’
}
5. If we need checkbox, radio button at node level then set checkbox: true , radio: true
Complete code for search, checkbox, radio button and link at leaf node
<script class=”code” type=”text/javascript”>
$(function () {
// init the tree
$(‘#tree’).aciTree({
ajax: {
//Calling controller method
url: ‘/Home/GetTreeView’
},
//this code is for making leafe lavel node as link
itemHook: function (parent, item, itemData, level) {
if (!itemData.inode) {
// a custom item implementation to show a link
this.setLabel(item, {
label: ‘<a href=”‘ + itemData[‘myurl’] + ‘” target=”_blank” title=”Click to open ‘ + itemData[‘myurl’] + ‘”>’ + itemData.label + ‘</a>’
});
}
},
//if we need check box then just set it as true
checkbox: true,
radio: true,
// our custom filter/search
filterHook: function (item, search, regexp) {
if (search.length) {
// try to get the parent
var parent = this.parent(item);
if (parent.length) {
// get parent label
var label = this.getLabel(parent);
if (regexp.test(String(label))) {
// all direct childrens match
return true;
}
}
// match the item
return regexp.test(String(this.getLabel(item)));
} else {
// empty search, all matches
return true;
}
},
});
var api = $(‘#tree’).aciTree(‘api’);
$(‘#search’).val(”)
var last = ”;
//its for searching the information
$(‘#search’).keyup(function () {
if ($(this).val() == last) {
return;
}
last = $(this).val();
api.filter(null, {
search: $(this).val(),
success: function (item, options) {
if (!options.first) {
alert(‘No results found!’);
}
}
});
});
});
</script>
JSON data format
1. Need to create a model class for n level tree with following properties
public class TreeNode
{
public int id { get; set; }
public int? parent { get; set; }
public string label { get; set; }
public bool inode { get; set; } //this if for if node have any child node
public bool open { get; set; } //this is for opening the node by default
public bool checkbox { get; set; } // this is for displaying checkbox at node
public bool radio { get; set; } //this is for displaying radio button at node
public string myurl { get; set; } // this is for setting URL for navigation
public List<TreeNode> branch { get; set; } // this is for child nodes
public TreeNode()
{
branch = new List<TreeNode>();
}
}
2. Need to return data in JSON format to view (Controller method)
public JsonResult GetTreeView()
{
var result = GetAllNodes();
return Json(result, JsonRequestBehavior.AllowGet);
}
//Controller method with sample data
public List<TreeNode> GetAllNodes()
{
var list = new List<TreeNode>
{
new TreeNode{ id = 1, label = “Root” ,checkbox=true, inode=true, radio=false, open=true },
new TreeNode{ id = 2, parent= 1, label = “Node-1.1”, checkbox=false, inode=true, radio=true, open=true },
new TreeNode{ id = 3, parent= 2, label = “Node-1.1.1″ , checkbox=false,inode=false, radio=false, open=true ,myurl=”http://google.com”},
new TreeNode{ id = 4, parent= 2, label = “Node-1.1.2″ , checkbox=false,inode=false, radio=false, open=true ,myurl=”http://facebook.com”},
new TreeNode{ id = 5, parent= 1, label = “Node-1.2” , checkbox=true,inode=true, radio=false, open=true },
new TreeNode{ id = 6, parent= 5, label = “Node-1.2.1” , checkbox=true,inode=false, radio=false, open=true },
new TreeNode{ id = 7, parent= 5, label = “Node-1.2.2”, checkbox=true,inode=false, radio=false, open=true },
new TreeNode{ id = 8, parent= 5, label = “Node-1.2.3” , checkbox=false,inode=true, radio=false, open=true },
new TreeNode{ id = 9, parent= 8, label = “Node-1.2.3.1”, checkbox=false,inode=true, radio=false, open=true },
new TreeNode{ id = 10, parent= 9, label = “Node-1.2.3.1.1” , checkbox=false,inode=false, radio=true, open=true }
};
//it’s an extension method for filling the Treende class
TreeNode tree = list.ToTree(); //this method is for filling data in class
List<TreeNode> lstTreeNode = new List<TreeNode>();
lstTreeNode.Add(tree);
return lstTreeNode;
}
Extension class for filling treenode class (its optional you can implement on your own)
public static class TreeNodeExtensions
{
public static TreeNode ToTree(this List<TreeNode> list)
{
if (list == null) throw new ArgumentNullException(“list”);
var root = list.SingleOrDefault(x => x.parent == null);
if (root == null) throw new InvalidOperationException(“root == null”);
PopulateChildren(root, list);
return root;
}
private static void PopulateChildren(TreeNode node, List<TreeNode> all)
{
var childs = all.Where(x => x.parent.Equals(node.id)).ToList();
foreach (var item in childs)
{
node.open = true;
//node.leaf = false;
node.branch.Add(item);
}
foreach (var item in childs)
all.Remove(item);
foreach (var item in childs)
PopulateChildren(item, all);
}
}
Sample output
The code can be downloaded from here.
You can access the portal here for a deep dive into all of the areas mentioned above.