- Home
- Forum
- ASP.NET Core - EJ 2
- How many levels can the Dropdown Tree display?
How many levels can the Dropdown Tree display?
All the examples have a 2-level tree. However, the place I'd use it would have 3 levels. Like "Animal -> Bird -> Parrot" and "Animal -> Bird -> Eagle".
Hi R Brian,
Greetings from Syncfusion support
We have reviewed your query and understand that you need to know how many levels can be displayed in the Dropdown Tree Component. We would like to inform you that there is no specific limit to the number of levels; you can set any number of levels based on the input width. If the width is minimal, a horizontal scrollbar will be added. In this sample, we have used 25 levels.
Refer to the code snippet below for reference.
[Index.cshtml]
|
….
<ejs-dropdowntree id="tree" popupHeight="200px" mode="Box" placeholder="Select a building" > <e-dropdowntree-fields dataSource="ViewBag.dataSource" value="id" parentValue="pid" hasChildren="hasChild" text="name"></e-dropdowntree-fields> </ejs-dropdowntree> … |
[Index.cshtml]
|
….
List<object> treedata = new List<object> { new { id = 1, name = "Discover Music", hasChild = true, expanded = true }, new { id = 2, pid = 1, name = "Hot Singles", hasChild = true, expanded = true }, new { id = 3, pid = 2, name = "Rising Artists", hasChild = true, expanded = true }, new { id = 4, pid = 3, name = "Live Music", hasChild = true, expanded = true }, new { id = 5, pid = 4, name = "Sales and Events", hasChild = true, expanded = true }, new { id = 6, pid = 5, name = "100 Albums - $5 Each", hasChild = true, expanded = true }, new { id = 7, pid = 6, name = "Hip-Hop and R&B Sale", hasChild = true, expanded = true }, new { id = 8, pid = 7, name = "Top Charts", hasChild = true, expanded = true }, new { id = 9, pid = 8, name = "Pop Hits", hasChild = true, expanded = true }, new { id = 10, pid = 9, name = "Rock Classics", hasChild = true, expanded = true },
… |
Sample: attached as zip file.
Please check the sample and let us know if you need any further assistance.
Best Regards,
Vishwanathan
Attachment: DropdownTree_dae30780.zip
Thank you! That will make my UI a lot more usable.
Next question: I'm trying to put the DropDownTree into a datagrid. I've paralleled the examples for other editor types, with an "edit" tag field pointing to a set of Javascript functions. However, I'm having trouble passing the DropDownTree's datasource.
My javascript currently is:
function writeTypeAC(args) {
typeDDTElement = new ej.dropdowns.DropDownTree({
value: args.rowData[args.column.field],
placeholder: "Select variant",
fields: {
dataSource: @Model.DDTData,
value: "id",
parentValue: "pid",
hasChildren: "hasChild",
selectable: "selectable"
}
});
typeDDTElement.appendTo(typeElement);
}
where DDTData is a string property with the JSON-serialized list created in the pagemodel. However, as the screenshot below shows, it ends up with " in the string instead of the proper JSON.
I've also tried passing the list object directly, without serializing it manually, but then I get something like "datasource: System.List.Generic.List'1<System.object>" in the generated script.
How do I pass the list into the JS write function? Conversely, is it possible to use an embedded C# declaration or razor tag for the element instead of a JS one?
Hi R Brian,
We have reviewed your query and understand that you are facing issues while binding the datasource. You can utilize the C# list datasource for the Dropdown Tree. The Razor approach sample has already been shared in previous update. Additionally, if you want to add the Dropdown Tree dynamically, the current approach is correct. We would like to clarify that the value property should be of the string[] type.
Refer to the code snippet below for reference.
[Index.cshtml]
|
….
<div id="tree"></div> <script> document.addEventListener("DOMContentLoaded", function () { const dropdownTree = new ej.dropdowns.DropDownTree({ placeholder: "Select a detail", fields: { dataSource: @Html.Raw(Json.Serialize(ViewBag.dataSource)), value: "id", parentValue: "pid", text: "name", hasChildren: "hasChild", selectable: "selectable" }, popupHeight: "200px", width: "300px" }); dropdownTree.appendTo("#tree"); }); </script> … |
[HomeController.cs]
|
….
List<object> treedata = new List<object> { new { id = 1, name = "Discover Music", hasChild = true, expanded = true }, new { id = 2, pid = 1, name = "Hot Singles", hasChild = true, expanded = true }, new { id = 3, pid = 2, name = "Rising Artists", hasChild = true, expanded = true }, new { id = 4, pid = 3, name = "Live Music", hasChild = true, expanded = true }, }; ViewBag.dataSource = treedata;
… |
Sample: attached as zip file.
Please check the sample and let us know if you need any further assistance.
Best Regards,
Vishwanathan
Attachment: DropdownTreedynamic_574b936b.zip
I've successfully gotten the binding to happen properly. Two remaining problems:
- The control takes quite a while (30 seconds or more) to create, whether embedded in the grid or as a standalone control.
- Once the page shows (after the above delay), the dropdown doesn't do anything. The arrow changes slightly as if it's dropping down, but either the contents are empty or something else is going wrong.
new ejs.dropdowns.DropDownTree({
"fields": {
"dataSource": ejs.data.DataUtil.parse.isJson([
{
"i": 1,
"t": "Dragon",
"c": true,
"s": false
},
{
"i": 1,
"p": 1,
"t": "Axolotl",
"c": true,
"s": false
},
{
"i": 36,
"p": 1,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 37,
"p": 1,
"t": "Small",
"c": false,
"s": true
},
{
"i": 38,
"p": 1,
"t": "Winged small",
"c": false,
"s": true
},
{
"i": 39,
"p": 1,
"t": "Winged baby",
"c": false,
"s": true
},
{
"i": 11,
"p": 1,
"t": "Pumpkin Wyvern",
"c": true,
"s": false
},
{
"i": 72,
"p": 11,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 73,
"p": 11,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 13,
"p": 1,
"t": "Crystal",
"c": true,
"s": false
},
{
"i": 50,
"p": 13,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 51,
"p": 13,
"t": "Small",
"c": false,
"s": true
},
{
"i": 52,
"p": 13,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 53,
"p": 13,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 54,
"p": 13,
"t": "Keychain - Adult Head",
"c": false,
"s": true
},
{
"i": 55,
"p": 13,
"t": "Keychain - Baby Head",
"c": false,
"s": true
},
{
"i": 20,
"p": 1,
"t": "Butterfly",
"c": true,
"s": false
},
{
"i": 40,
"p": 20,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 41,
"p": 20,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 42,
"p": 20,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 22,
"p": 1,
"t": "Flying Serpent",
"c": true,
"s": false
},
{
"i": 62,
"p": 22,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 63,
"p": 22,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 64,
"p": 22,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 65,
"p": 22,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 66,
"p": 22,
"t": "Keychain - Adult head",
"c": false,
"s": true
},
{
"i": 67,
"p": 22,
"t": "Keychain - Baby head",
"c": false,
"s": true
},
{
"i": 82,
"p": 22,
"t": "Earrings",
"c": false,
"s": true
},
{
"i": 23,
"p": 1,
"t": "Woodland",
"c": true,
"s": false
},
{
"i": 74,
"p": 23,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 75,
"p": 23,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 76,
"p": 23,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 77,
"p": 23,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 78,
"p": 23,
"t": "Keychain - Adult head",
"c": false,
"s": true
},
{
"i": 79,
"p": 23,
"t": "Keychain - Baby head",
"c": false,
"s": true
},
{
"i": 27,
"p": 1,
"t": "Dune Striker",
"c": true,
"s": false
},
{
"i": 59,
"p": 27,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 60,
"p": 27,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 61,
"p": 27,
"t": "Keychain - Adult head",
"c": false,
"s": true
},
{
"i": 32,
"p": 1,
"t": "Storm",
"c": true,
"s": false
},
{
"i": 84,
"p": 32,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 47,
"p": 1,
"t": "Coral Reef",
"c": true,
"s": false
},
{
"i": 43,
"p": 47,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 44,
"p": 47,
"t": "Small Adult",
"c": false,
"s": true
},
{
"i": 46,
"p": 47,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 47,
"p": 47,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 48,
"p": 47,
"t": "Keychain - Baby Head",
"c": false,
"s": true
},
{
"i": 49,
"p": 47,
"t": "Keychain - Adult Head",
"c": false,
"s": true
},
{
"i": 80,
"p": 47,
"t": "Earrings",
"c": false,
"s": true
},
{
"i": 69,
"p": 1,
"t": "Wolfdragon",
"c": true,
"s": false
},
{
"i": 83,
"p": 69,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 79,
"p": 1,
"t": "Phoenix",
"c": true,
"s": false
},
{
"i": 68,
"p": 79,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 69,
"p": 79,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 70,
"p": 79,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 71,
"p": 79,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 80,
"p": 1,
"t": "Crystalwing",
"c": true,
"s": false
},
{
"i": 56,
"p": 80,
"t": "Small",
"c": false,
"s": true
},
{
"i": 57,
"p": 80,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 58,
"p": 80,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 81,
"p": 80,
"t": "Earrings",
"c": false,
"s": true
},
{
"i": 101,
"p": 1,
"t": "Gemstone",
"c": true,
"s": false
},
{
"i": 85,
"p": 101,
"t": "Baby",
"c": false,
"s": true
},
{
"i": 86,
"p": 101,
"t": "Small adult",
"c": false,
"s": true
},
{
"i": 87,
"p": 101,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 88,
"p": 101,
"t": "Tadling",
"c": false,
"s": true
},
{
"i": 89,
"p": 101,
"t": "Earrings",
"c": false,
"s": true
},
{
"i": 102,
"p": 1,
"t": "Clover",
"c": true,
"s": false
},
{
"i": 100,
"p": 102,
"t": "Earrings",
"c": false,
"s": true
},
{
"i": 2,
"t": "Egg",
"c": true,
"s": false
},
{
"i": 62,
"p": 2,
"t": "Dragonscale",
"c": true,
"s": false
},
{
"i": 91,
"p": 62,
"t": "Small",
"c": false,
"s": true
},
{
"i": 76,
"p": 2,
"t": "Crystal",
"c": true,
"s": false
},
{
"i": 90,
"p": 76,
"t": "Small",
"c": false,
"s": true
},
{
"i": 109,
"p": 76,
"t": "Small 2 color",
"c": false,
"s": true
},
{
"i": 4,
"t": "African Violet Pot",
"c": true,
"s": false
},
{
"i": 82,
"p": 4,
"t": "Smiley",
"c": true,
"s": false
},
{
"i": 11,
"p": 82,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 12,
"p": 82,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 13,
"p": 82,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 85,
"p": 4,
"t": "Heart Smiley",
"c": true,
"s": false
},
{
"i": 2,
"p": 85,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 3,
"p": 85,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 4,
"p": 85,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 89,
"p": 4,
"t": "Spiral 1",
"c": true,
"s": false
},
{
"i": 14,
"p": 89,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 15,
"p": 89,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 16,
"p": 89,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 104,
"p": 89,
"t": "6\u0022",
"c": false,
"s": true
},
{
"i": 92,
"p": 4,
"t": "Spiral 2",
"c": true,
"s": false
},
{
"i": 17,
"p": 92,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 18,
"p": 92,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 19,
"p": 92,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 105,
"p": 92,
"t": "6\u0022",
"c": false,
"s": true
},
{
"i": 95,
"p": 4,
"t": "Spiral Rib",
"c": true,
"s": false
},
{
"i": 20,
"p": 95,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 21,
"p": 95,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 22,
"p": 95,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 106,
"p": 95,
"t": "6\u0022",
"c": false,
"s": true
},
{
"i": 98,
"p": 4,
"t": "Straight Rib",
"c": true,
"s": false
},
{
"i": 23,
"p": 98,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 24,
"p": 98,
"t": "3\u0022:",
"c": false,
"s": true
},
{
"i": 25,
"p": 98,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 107,
"p": 98,
"t": "6\u0022",
"c": false,
"s": true
},
{
"i": 103,
"p": 4,
"t": "Tongue Smiley",
"c": true,
"s": false
},
{
"i": 101,
"p": 103,
"t": "2\u0022",
"c": false,
"s": true
},
{
"i": 102,
"p": 103,
"t": "3\u0022",
"c": false,
"s": true
},
{
"i": 103,
"p": 103,
"t": "4\u0022",
"c": false,
"s": true
},
{
"i": 5,
"t": "Decoration",
"c": true,
"s": false
},
{
"i": 9,
"p": 5,
"t": "Drac-o-lantern",
"c": true,
"s": false
},
{
"i": 99,
"p": 9,
"t": "Small",
"c": false,
"s": true
},
{
"i": 108,
"p": 9,
"t": "Small 2 color",
"c": false,
"s": true
},
{
"i": 7,
"t": "Critter",
"c": true,
"s": false
},
{
"i": 41,
"p": 7,
"t": "Husky Pup",
"c": true,
"s": false
},
{
"i": 28,
"p": 41,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 29,
"p": 41,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 43,
"p": 7,
"t": "Bat",
"c": true,
"s": false
},
{
"i": 26,
"p": 43,
"t": "Large",
"c": false,
"s": true
},
{
"i": 27,
"p": 43,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 118,
"p": 43,
"t": "Small",
"c": false,
"s": true
},
{
"i": 45,
"p": 7,
"t": "Octopus",
"c": true,
"s": false
},
{
"i": 93,
"p": 45,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 57,
"p": 7,
"t": "Spider",
"c": true,
"s": false
},
{
"i": 98,
"p": 57,
"t": "Wolf Large",
"c": false,
"s": true
},
{
"i": 120,
"p": 57,
"t": "Santa",
"c": false,
"s": true
},
{
"i": 121,
"p": 57,
"t": "Wolf Small",
"c": false,
"s": true
},
{
"i": 58,
"p": 7,
"t": "Pumpkin Snail",
"c": true,
"s": false
},
{
"i": 94,
"p": 58,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 59,
"p": 7,
"t": "Snail",
"c": true,
"s": false
},
{
"i": 96,
"p": 59,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 61,
"p": 7,
"t": "Bumpkinurtle",
"c": true,
"s": false
},
{
"i": 92,
"p": 61,
"t": "Large",
"c": false,
"s": true
},
{
"i": 119,
"p": 61,
"t": "Small",
"c": false,
"s": true
},
{
"i": 63,
"p": 7,
"t": "Dragonfly",
"c": true,
"s": false
},
{
"i": 33,
"p": 63,
"t": "Small",
"c": false,
"s": true
},
{
"i": 64,
"p": 7,
"t": "Snowflurtle",
"c": true,
"s": false
},
{
"i": 97,
"p": 64,
"t": "Large",
"c": false,
"s": true
},
{
"i": 116,
"p": 64,
"t": "Small",
"c": false,
"s": true
},
{
"i": 117,
"p": 64,
"t": "Keychain",
"c": false,
"s": true
},
{
"i": 65,
"p": 7,
"t": "Pumpkinurtle",
"c": true,
"s": false
},
{
"i": 95,
"p": 65,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 73,
"p": 7,
"t": "Duck",
"c": true,
"s": false
},
{
"i": 30,
"p": 73,
"t": "Yellow",
"c": false,
"s": true
},
{
"i": 31,
"p": 73,
"t": "Canada Goose",
"c": false,
"s": true
},
{
"i": 32,
"p": 73,
"t": "Mallard",
"c": false,
"s": true
},
{
"i": 110,
"p": 73,
"t": "Canada Goose small",
"c": false,
"s": true
},
{
"i": 111,
"p": 73,
"t": "Canada Goose keychain",
"c": false,
"s": true
},
{
"i": 112,
"p": 73,
"t": "Yellow small",
"c": false,
"s": true
},
{
"i": 113,
"p": 73,
"t": "Yellow keychain",
"c": false,
"s": true
},
{
"i": 114,
"p": 73,
"t": "Mallard small",
"c": false,
"s": true
},
{
"i": 115,
"p": 73,
"t": "Mallard keychain",
"c": false,
"s": true
},
{
"i": 77,
"p": 7,
"t": "TRex",
"c": true,
"s": false
},
{
"i": 34,
"p": 77,
"t": "Tiny",
"c": false,
"s": true
},
{
"i": 35,
"p": 77,
"t": "Keychain",
"c": false,
"s": true
}
]),
"hasChildren": "c",
"parentValue": "p",
"selectable": "s",
"text": "t",
"value": "i"
},
"ignoreAccent": false,
"mode": "Default",
"zIndex": 1000.0
}).appendTo("#tree");
Hi R Brian,
We have reviewed your query and understand that you are facing delays while rendering the Dropdown Tree component. We prepared a sample with your shared code and replicated the issue. Upon further validation, we found that you are using the same value for two data entries, causing an infinite loop while rendering subchildren, which is the reason for the performance delay. We would like to clarify that “value” field should be unique to avoid such issues. After modifying the duplicate IDs, the Dropdown Tree works properly.
Issue code:
|
new ejs.dropdowns.DropDownTree({ "fields": { "dataSource": ejs.data.DataUtil.parse.isJson([ { "i": 1, "t": "Dragon", "c": true, "s": false }, { "i": 1, "p": 1, "t": "Axolotl", "c": true, "s": false }, |
Sample: Attached as zip file.
Please check the sample and let us know if you need any further assistance.
Best Regards,
Vishwanathan
Attachment: DDTJson_c177f64a.zip
So, to be clear - the child IDs cannot be the same as their parents? That doesn't make a lot of sense, at least when using IDs that come out of a database, and are assigned automatically as record IDs in different tables. There's no way that these can be unique, at least where a multi-table parent-child database is concerned. I'll see if I can find a workaround. The only IDs that really matter in the database are the ones for the leaf nodes, as they're the only ones selectable.
Hi R Brian,
We recognize that your datasource is created from a database with multiple tables, where some items share the same ID. We recommend that you map a different field for the value field rather than using the currently mapped field "i." The new field should be unique. This change will enable you to maintain similar IDs in your datasource while ensuring that the Dropdown Tree renders correctly.
Refer to the code snippet below for reference.
|
…. new ejs.dropdowns.DropDownTree({ "fields": { "dataSource": ejs.data.DataUtil.parse.isJson([ { "i": 1, // Same Id, “NewId”:1, // unique ID "t": "Dragon", "c": true, "s": false }, { "i": 1, //Same Id “NewId”:2, // unique Id "p": 1, "t": "Axolotl", "c": true, "s": false }, …
"hasChildren": "c", "parentValue": "p", "selectable": "s", "text": "t", "value": " NewId " }, "ignoreAccent": false, "mode": "Default", "zIndex": 1000.0 }).appendTo("#tree");
…. |
Regards,
Vishwanathan
My approach was different - for all layers except for the actual leaf nodes, which were the only selectable things, I put a sequential negative ID instead of the actual database ID. For the leaf nodes, I put the actual database ID, since that's what I need to store in the database record that's being edited.
My remaining issue is one that I'm not sure the control is able to handle. Many of the leaf nodes have the same text - for example, if the top level is Dragon, mid-level is Crystal, it has both Baby and Adult as text on the leaf nodes. However, Dragon | Storm has the same two entries. The text that's displayed in the grid after selection is just the leaf node text, i.e. "Baby". This doesn't give a great deal of information to the user about which item is actually selected.
Is there any way (either at the grid level or in the control) to replace the control's text (i.e., "Baby") with a more complete text like "Dragon | Crystal | Baby" or something similar? I can provide the datasource mapping the same integer ID value to a more complete text value, which is actually what's currently driving the dropdown control that I'm using in the grid.
Thank you for all your help so far, it's greatly appreciated.
Hi R Brian,
We have reviewed your query and understand that you want to display the hierarchy of nodes instead of the default text. We suggest using the valueTemplate property to customize the value. In the valueTemplate, you can get the parent node using the getData method. This will allow us to show the node hierarchy when a node is selected. As mentioned earlier, this will work properly only if you use a unique ID for each node. Therefore, we have modified the data source accordingly.
Refer to the below code snippet for reference.
|
…
"ignoreAccent" : false, "mode" : "Default", "zIndex" : 1000.0, "valueTemplate": function (data) { let text = data.t; let parent = data.p ? getParentText(data.p) : ''; return parent ? `${parent} | ${text}` : text; } }) instance.appendTo("#tree"); function getParentText(parentId) { var data = instance.getData(); let parentItem = (data).find(item => item.i === parentId); if (parentItem) { let grandParent = parentItem.p ? getParentText(parentItem.p) : ''; return grandParent ? `${grandParent} | ${parentItem.t}` : parentItem.t; } return ''; } }); </script>
….
|
Sample: attached as zip file.
Please check the sample and let us know if you need any further assistance.
Best Regards,
Vishwanathan
Attachment: DDTvalueTemplate_a345e284.zip
- 9 Replies
- 2 Participants
-
RB R Brian Lindahl
- Nov 22, 2024 03:21 PM UTC
- Dec 5, 2024 04:42 PM UTC