Introduction
Many times, we required to display data in treeview
, such as showing folder structure. Best feature of this solution is not to worry about level of treeview
because I found many articles on treeview
but that having limitation of levels or levels are static. We can bind treeview
in many ways like through XML or through treeview
object, but the problem with XML is we need extra logic to create XML. So here I am providing a very simple solution to bind treeview
for that we required data in list. I elaborate this article in such a way that it can implement in any type of language, that’s why I put in more concentration towards the algorithm and not towards the source code.
Algorithm
This algorithm is divided into two parts, that is:
- Assign unique value to each node, and
- Based on unique value, generate
treeview
Assigning Unique Value to Each Node
Algorithm
- Take next item from list and slit into ‘/’
- Take next node from split item
- If node contains extension, then just return to step a.
- If node index is zero, then append some text to node such as “
<N1>
.
- If node index > zero, then append text to node in the following way:
Node=FirstCharecterOfNode(index-1)+Node+ FirstCharecterOfNode(index+1)
- Return to step b.
Source Code
Data <string>=
{
"A/F1.txt"
"A/B/F2.txt"
"A/B/F3.txt"
"A/B/C/F4.txt"
"A/B/C/F5.txt"
"A/D/C/F6.txt"
"A/D/C/F7.txt"
}
List<string> Data = new List<string>();
List<string> ResultData = new List<string>();
for (int i = 0; i < Data.Count; ++i)
{
string Result = "";
Data[i] = Data[i].Replace('\\', '/');
for (int j = 0; j < Data[i].Split('/').Length; ++j)
{
string BindText = Data[i].Split('/')[j];
if (j == 0)
{
BindText = BindText + "<12>";
Result = BindText;
}
else if (BindText.Contains("."))
{
Result = Result + "/" + BindText;
}
else
{
BindText = BindText + "<" + Data[i].Split('/')[j - 1].Substring(0, 1) +
"XZE" + BindText.Substring(0, 1) + ">";
Result = Result + "/" + BindText;
}
}
ResultData.Add(Result);
}
Example
Input Value
List= {
"A/F1.txt"
"A/B/F2.txt"
"A/B/F3.txt"
"A/B/C/F4.txt"
"A/B/C/F5.txt"
"A/D/C/F6.txt"
"A/D/C/F7.txt"
}
Output Value
List= {
"A<N1>/F1.txt"
"A<N1>/B<ABC>/F2.txt"
"A<N1>/B<ABC>/F3.txt"
"A<N1>/B<ABC>/C<BC>/F4.txt"
"A<N1>/B<ABC>/C<BC>/F5.txt"
"A<N1>/D<ADC>/C<DC>/F6.txt"
"A<N1>/D<ADC>/C<DC>/F7.txt"
}
2. Generate Treeview object based on unique id which assigns in the previous algorithm:
Algorithm
- Declare
CurrentNode
, RootNode
- Take next item from list and slit into ‘/’
- Take next node from split item
- If node is in first item and index is zero, then:
CurrentNode=CreateNode();
RootNode=CurrentNode;
- Else if node index is zero, then
CurrentNode= RootNode;
- Else id node is File name, then
MyNode= CreateNode();
- Add
MyNode
into CurrentNode
- Else
Text=GetNodeName(node);
ID=GetNodeID(node);
- Find
ID
into CurrentNode
- If Not match, then
MyNode=CreateNode()
- Add
MyNode
into CurrentNode
- Else (means Match), Then
CurrentNode=GetNodeBasedOnID(ID);
- If node is last item of list, then Exit
- If node is last item, then go to step b, else go to step c.
Source Code
Data<string>=
{
"A<N1>/F1.txt",
"A<N1>/B<ABC>/F2.txt",
"A<N1>/B<ABC>/F3.txt",
"A<N1>/B<ABC>/C<BC>/F4.txt",
"A<N1>/B<ABC>/C<BC>/F5.txt",
"A<N1>/D<ADC>/C<DC>/F6.txt",
"A<N1>/D<ADC>/C<DC>/F7.txt",
}
DocIDs<string>=
{
"1",
"2",
"3",
"4",
"5",
"6",
"7"
}
List<string> Data, List<string> DocIDs;
List<TreeItem> Root = new List<TreeItem>();
TreeItem RootNode = new TreeItem();
for (int i = 0; i < Data.Count; ++i)
{
string Prev = "";
string Next = "";
TreeItem PreNode = new TreeItem();
TreeItem CurrentNode = new TreeItem();
CurrentNode = RootNode;
for (int j = 0; j < Data[i].Split('/').Length; ++j)
{
string BindText = Data[i].Split('/')[j];
string id = "";
string text = "";
if (i == 0 && j == 0)
{
text = BindText.Substring(0, BindText.IndexOf('<'));
id = ((BindText.Replace(text, "")).Replace("<",
"")).Replace(">", "");
CurrentNode = new TreeItem() { ID = id, Text = text };
RootNode = CurrentNode;
}
else if (j == 0)
{
CurrentNode = RootNode;
}
else if (BindText.Contains("."))
{
text = BindText;
CurrentNode.Items = new List<TreeItem>();
CurrentNode.Items.Add(new TreeItem() { UniqueID = id, Text = text, ID = DocIDs[i] });
}
else
{
text = BindText.Substring(0, BindText.IndexOf('<'));
BindText = BindText.Remove(0, BindText.IndexOf('<'));
id = (BindText.Replace("<", "")).Replace(">", "");
if (CurrentNode.Items == null)
{
CurrentNode.Items = new List<TreeItem>();
}
if (CurrentNode.Items.Count(m => m.UniqueID == id) == 0)
{
PreNode = CurrentNode;
CurrentNode = new TreeItem() { UniqueID = id, Text = text, ID = DocIDs[i] };
PreNode.Items.Add(CurrentNode);
}
else
{
CurrentNode = CurrentNode.Items.Single(m => m.UniqueID == id);
}
}
}
}
Root.Add(RootNode);
return Root;
Step to Implement Treeview
Please follows steps below:
Create TreeView Class
public class TreeItem
{
public string Text { get; set; }
public string ID { get; set; }
public string URL { get; set; }
public string UniqueID { get; set; }
public string DetailText { get; set; }
public List<TreeItem> Items { get; set; }
}
Create TreeBinder class
public class TreeBinder
{
private List<string> AssignUniqueValue(List<string> Data)
{
List<string> ResultData = new List<string>();
for (int i = 0; i < Data.Count; ++i)
{
string Result = "";
Data[i] = Data[i].Replace('\\', '/');
for (int j = 0; j < Data[i].Split('/').Length; ++j)
{
string BindText = Data[i].Split('/')[j];
if (j == 0)
{
BindText = BindText + "<12>";
Result = BindText;
}
else if (BindText.Contains("."))
{
Result = Result + "/" + BindText;
}
else
{
BindText = BindText + "<" + Data[i].Split('/')[j - 1].Substring(0, 1) +
"XZE" + BindText.Substring(0, 1) + ">";
Result = Result + "/" + BindText;
}
}
ResultData.Add(Result);
}
return ResultData;
}
private List<TreeItem> GenerateTreeViewBasedOnUniueData(List<string> Data, List<string> DocIDs)
{
List<TreeItem> Root = new List<TreeItem>();
TreeItem RootNode = new TreeItem();
for (int i = 0; i < Data.Count; ++i)
{
string Prev = "";
string Next = "";
TreeItem PreNode = new TreeItem();
TreeItem CurrentNode = new TreeItem();
CurrentNode = RootNode;
for (int j = 0; j < Data[i].Split('/').Length; ++j)
{
string BindText = Data[i].Split('/')[j];
string id = "";
string text = "";
if (i == 0 && j == 0)
{
text = BindText.Substring(0, BindText.IndexOf('<'));
id = ((BindText.Replace(text, "")).Replace
("<", "")).Replace(">", "");
CurrentNode = new TreeItem() { ID = id, Text = text };
RootNode = CurrentNode;
}
else if (j == 0)
{
CurrentNode = RootNode;
}
else if (BindText.Contains("."))
{
text = BindText;
CurrentNode.Items = new List<TreeItem>();
CurrentNode.Items.Add(new TreeItem() { UniqueID = id, Text = text, ID = DocIDs[i] });
}
else
{
text = BindText.Substring(0, BindText.IndexOf('<'));
BindText = BindText.Remove(0, BindText.IndexOf('<'));
id = (BindText.Replace("<", "")).Replace(">", "");
if (CurrentNode.Items == null)
{
CurrentNode.Items = new List<TreeItem>();
}
if (CurrentNode.Items.Count(m => m.UniqueID == id) == 0)
{
PreNode = CurrentNode;
CurrentNode = new TreeItem() { UniqueID = id, Text = text, ID = DocIDs[i] };
PreNode.Items.Add(CurrentNode);
}
else
{
CurrentNode = CurrentNode.Items.Single(m => m.UniqueID == id);
}
}
}
}
Root.Add(RootNode);
return Root;
Declare TreeView control in view
<script type="text/javascript">
function BindTreeView() {
console.log("start");
var url = '/NMA/LoadTree' $.post(url,
function (data) {
console.log(data);
$("#tree").igTree({
dataSource: data, bindings: {
textKey: "Text",
valueKey: "ID",
childDataProperty: "Items",
bindings: {
textKey: "Text",
valueKey: "ID"
}
}
});
});
}
</script>
<button type="button" value="test" onclick="BindTreeView();">Click me</button>
<ul id="tree"></ul>
Called tree binder method from controller
public JsonResult LoadTree()
{
string[] Data ={
"A/F1.txt",
"A/B/F2.txt",
"A/B/F3.txt",
"A/B/C/F4.txt",
"A/B/C/F5.txt",
"A/D/C/F6.txt",
"A/D/C/F7.txt"
};
string[] DocIDs ={
"1",
"2",
"3",
"4",
"5",
"6",
"7"
};
TreeBinder treObj = new TreeBinder();
List<TreeItem> tree = treObj.GenerateTreeView(Data.ToList(), DocIDs.ToList());
return Json(tree, JsonRequestBehavior.AllowGet);
}