Unlimited ratings
Many times we are unsure of the hierarchy of hierarchy, and this time we need to use infinite grading.
When it comes to infinite grading, it is also called recursive. (it is said that frequent recursion is a very expensive performance), where we need to design a table mechanism to store infinitely graded data. Of course, the following are self-tinkering results, non-standard. Who has better design hope not stingy enlighten.
In fact, it is simply a relationship between an ID and a parent ID.
And so on, the ID needs to be unique, the Parenid need to be in the ID column inside can exist. This allows us to achieve infinite grading, which is perfect if you add a column of sort.
Jstree Plug-in
Official address: https://www.jstree.com/
Why use this plugin? Because there is a convenient API for us to do data binding, and Support node drag to implement additions and deletions, the personal feel that this function is very powerful.
Demo
Let's follow the Jstree plug-in to achieve unlimited hierarchical data operations. Take the area data operation as an example and write the demo code in the form of code first.
Create a region entity
In order to match the node ID generated automatically by the plugin, we use node and parentnode here to store the subordinate relationship (not the ID and ParentID mentioned above, but the actual effect is the same).
<summary>///Area//</summary>public class region{//<summary>/// PRIMARY Key ID// </ summary> public int Id {get; set;} <summary>///// </summary> Public string name {get; set;} <summary>////// </summary> Public string Node {get; set;} <summary>//parent node/// </summary> public string ParentNode {get; set;}}
Data object dto that satisfies the Jstree plug-in
To accommodate the data requirements of the Jstree plug-in, we need to convert the above data into a tree-like data object.
<summary>
Dto
</summary>
public class Regionstreeoutput
{
<summary>
Id
</summary>
public int Regionsid {get; set;}
<summary>
Tree display text (corresponding to region's name)
</summary>
public string text {get; set;}
<summary>
Tree ID (corresponding to node)
</summary>
public string ID {get; set;}
<summary>
Child node data (this attribute represents the hierarchical relationship of data)
</summary>
Public list<regionstreeoutput> Children {get; set;}
}
View Code
Data conversion
An auxiliary method for #region Getregiontree initialization of data acquisition
Public Regionstreeoutput loadregions (string ID, list<region> inregions, Regionstreeoutput outregions)
{
List<region> regions = inregions.where (t = = T.parentnode = = ID). ToList ();
if (outregions = = null)//Load parent node
{
Outregions = Totreedata (Regions[0]);
Loadregions (Outregions.id, inregions, outregions);
}
else//Load child node
{
Outregions.children = Totreesdata (regions);
if (regions. Count > 0)
{
for (int i = 0; I < regions. Count; i++)
{
Loadregions (regions[i]. Node, Inregions, outregions.children[i]);//Recursive call to
}
}
}
return outregions;
}
Public Regionstreeoutput totreedata (region)
{
var treedata = new Regionstreeoutput ();
treedata.id = region. Node;
Treedata.text = region. Name;
Treedata.regionsid = region. Id;
return treedata;
}
Public list<regionstreeoutput> Totreesdata (list<region> listregion)
{
var regions = new list<regionstreeoutput> ();
for (int i = 0; i < Listregion.count; i++)
{
Regions. ADD (Totreedata (listregion[i));
}
return regions;
}
#endregion
Initialize to get transformed data
<summary>///initialization data acquisition///</summary>//<returns></returns> public Jsonresult Getresultdata () { Treedbcontext db = new Treedbcontext (); var regions = db. Regions.where (t = True). ToList (); var regionobj = loadregions ("1", regions, null); Return Json (regionobj); }
The above background data is almost complete.
Foreground data loading
$ (function () {
$.post ("/home/getresultdata", NULL, function (SData) {
Treeobj = $ (' #jstree_demo '). Jstree ({
, "checkbox"
' Plugins ': ["ContextMenu", "DND", "Search", "state", "types", "Wholerow"],
' Core ': {
"Animation": 0,
"Check_callback": true,
' Force_text ': true,
"Themes": {"Stripes": true},
' Data ': sData
},
"Types": {
"Default": {
"icon": "FA fa-folder icon-state-warning icon-lg"
},
"File": {
"icon": "FA fa-file icon-state-warning icon-lg"
}
},
"ContextMenu": {
Select_node:false,
Show_at_node:true,
Items:function (o, CB) {
Because here we need to define more than one item, so we return it by object.
var actions = {};
Add a "new" right-click menu
Actions.create = {//Here the Create is actually wide to be arbitrarily named, the key is inside the inside of this action callback method
"Separator_before": false,//create this one before the split line
"Separator_after": true,//create this one after the split line
"_disabled": false,//false indicates that create this item can be used; True indicates that you cannot use
"Label": "New",//create the name of this item can be customized
"Action": function (data) {//Click Create to trigger the method, which is quite useful.
var inst = $.jstree.reference (data.reference),
obj = Inst.get_node (data.reference);//Get the current node and get all the properties of the current node
New node, the following three lines of code comment out will not add the node
Inst.create_node (obj, {}, "last", function (New_node) {
SetTimeout (function () {inst.edit (New_node);}, 0);//triggers a rename method after the node is added, that is, the node can be renamed immediately after the creation node is complete
});
}
};
if (o.id! = "0001")//masking The operation of the root node "0001" to the root node corresponding to the True ID
{
Add a "rename" Right-click menu
Actions.rename = {
"Separator_before": false,
"Separator_after": false,
"_disabled": false,//(This.check ("Rename_node", Data.reference, This.get_parent (data.reference), "")),
"Label": "Rename",
"Action": function (data) {
var inst = $.jstree.reference (data.reference),
obj = Inst.get_node (data.reference);
Inst.edit (obj);
}
}
Add a Delete right-click menu
Actions.delete = {
"Separator_before": false,
"Icon": false,
"Separator_after": false,
"_disabled": false,//(This.check ("Delete_node", Data.reference, This.get_parent (data.reference), "")),
"Label": "Delete",
"Action": function (data) {
var inst = $.jstree.reference (data.reference),
obj = Inst.get_node (data.reference);
if (inst.is_selected (obj)) {
Inst.delete_node (inst.get_selected ());
}
else {
Inst.delete_node (obj);
}
}
};
}
Return actions;//back to right-click menu item
}
},
});
});
});
Other operations
Delete the node $ (' #jstree_demo '). On (' Delete_node.jstree ', function (e, data) {var id = DATA.NODE.ORIGINAL.R Egionsid; $.ajax ({type: "Get", url: "/home/deleteregion?id=" + ID, success:function ( sData) {}}); });//Mobile Node $ (' #jstree_demo '). On (' Move_node.jstree ', function (e, data) {saveregions (data); });//Modify Name $ (' #jstree_demo '). On (' Rename_node.jstree ', function (e, data) {saveregions (data); });//Save function Saveregions (data) {var id = data.node.original.RegionsId; var name = data.node.text;//Modified name//var oldname = data.old;//original name//var Pnode = $ (' #j Stree_demo '). Jstree (). Get_node (data.node.parent). Original. Regionsid; var josndata = {"id": ID, "Node": Data.node.id, "parentnode": Data.node.parent, "name": name}; $.ajax ({URL: "/home/saveregions", Data:josndata, Success:function (sData) { Data.node.original.RegionsId = SData; data.node.state.opened = false;//is expanded}}); }
Of course, remember to modify or delete the ID of the corresponding background entity to fetch REGIONSID.
Use the button to manipulate and delete the changes
function Createtree () { var ref = $ (' #jstree_demo '). Jstree (True), sel = ref.get_selected (); if (!sel.length) {return false;} sel = sel[0]; sel = Ref.create_node (sel, {"type": "File"}); if (SEL) { ref.edit (SEL); }}; function Renametree () { var ref = $ (' #jstree_demo '). Jstree (True), sel = ref.get_selected (); if (!sel.length) {return false;} sel = sel[0]; Ref.edit (SEL, function () { });}; function DeleteTree () { var ref = $ (' #jstree_demo '). Jstree (True), sel = ref.get_selected (); if (!sel.length) {return false;} Ref.delete_node (sel);};
For more detailed details please see demo.
Unlimited grading and tree structure data additions and deletions "provide demo download"