Hello!
First of all I'm posting tihs in the DropDownTree section but I'm not convinced that the DropDownTree is necessarily the right component for what I want.
Basically I need to display something exactly like the autocomplete component but it must have a hierarchy, so the items displayed in this "autocomplete" can be a parent item or a child item and each child is linked to a parent and should be somehow intended. This looks like what the DropDownTree offers but I'm having several problems working with it.
In order to get my data, I need to call an external service which takes two parameters, the language and the search string (which should be whatever the user typed in the autocomplete box).
This is how I setup my DropDown:
01.
@(Html.Kendo().DropDownTree()
02.
.Name(
"search"
)
03.
//.DataTextField("name")
04.
.Placeholder(
"Search"
)
05.
.Filter(FilterType.Contains)
06.
.MinLength(2)
07.
.DataSource(dataSource => dataSource
08.
.Read(read => read
09.
.Action(
"Search"
,
"Blabla"
,
new
{ culture = Localizer.CultureName })
10.
.Data(
"onAdditionalData"
)
11.
)
12.
)
13.
)
14.
<input type=
"hidden"
id=
"searchFilter"
name=
"searchFilter"
/>
In onAdditionalData, I setup the two parameters that my Search action from the Blabla controller requires:
1.
<script>
2.
function
onAdditionalData() {
3.
return
{
4.
language:
"@Localizer.CultureName"
,
5.
searchString: $(
"#searchFilter"
).val()
6.
};
7.
}
8.
</script>
Since I didn't find an easy way to get the value that the user typed, I'm binding the filtering event like this and setting the value in a hidden field, which is then used by onAdditionalData to pass the search string:
01.
function
dropdowntree_filtering(e) {
02.
//get filter descriptor
03.
var
filter = e.filter;
04.
$(
"#searchFilter"
).val(filter.value);
05.
}
06.
07.
$(
function
() {
08.
$(document).ready(
function
() {
09.
var
dropdowntree = $(
"#search"
).data(
"kendoDropDownTree"
);
10.
dropdowntree.bind(
"filtering"
, dropdowntree_filtering);
11.
});
12.
});
Then my controller calls the service with the 2 parameters and that's fine, I get my results in essentially this format:
01.
[
02.
{
03.
"id"
:851,
04.
"name"
:
"Some name 1"
,
05.
"idParent"
:
null
,
06.
"children"
:[
07.
08.
]
09.
},
10.
{
11.
"id"
:402,
12.
"name"
:
"Some name 2"
,
13.
"idParent"
:
null
,
14.
"children"
:[
15.
{
16.
"id"
:403,
17.
"name"
:
"Some name 3"
,
18.
"idParent"
:402,
19.
"children"
:
null
20.
},
21.
{
22.
"id"
:404,
23.
"name"
:
"Some name 4"
,
24.
"idParent"
:402,
25.
"children"
:
null
26.
}
27.
]
28.
},
29.
{
30.
"id"
:923,
31.
"name"
:
"Some name 5"
,
32.
"idParent"
:
null
,
33.
"children"
:[
34.
{
35.
"id"
:929,
36.
"name"
:
"Some name 6"
,
37.
"idParent"
:923,
38.
"children"
:
null
39.
}
40.
]
41.
},
42.
{
43.
"id"
:728,
44.
"name"
:
"Some name 7"
,
45.
"idParent"
:727,
46.
"children"
:[
47.
{
48.
"id"
:734,
49.
"name"
:
"Some name 8"
,
50.
"idParent"
:728,
51.
"children"
:
null
52.
}
53.
]
54.
},
55.
{
56.
"id"
:757,
57.
"name"
:
"Some name 9"
,
58.
"idParent"
:727,
59.
"children"
:[
60.
{
61.
"id"
:763,
62.
"name"
:
"Some name 10"
,
63.
"idParent"
:757,
64.
"children"
:
null
65.
}
66.
]
67.
},
68.
{
69.
"id"
:405,
70.
"name"
:
"Some name 11"
,
71.
"idParent"
:
null
,
72.
"children"
:[
73.
{
74.
"id"
:406,
75.
"name"
:
"Some name 12"
,
76.
"idParent"
:405,
77.
"children"
:
null
78.
}
79.
]
80.
}
81.
]
Now my problem is that I don't know how to build a result set that the dropdowntree can display properly. I've tried to build a list of DropDownTreeItem like this:
01.
public
async Task<JsonResult> Search(
string
language,
string
searchString)
02.
{
03.
IReadOnlyCollection<MyDto> results = await _myService.Search(language, searchString);
04.
IList<DropDownTreeItem> items =
new
List<DropDownTreeItem>();
05.
foreach
(var r
in
results)
06.
{
07.
DropDownTreeItem item =
new
DropDownTreeItem
08.
{
09.
Id = r.Id?.ToString(),
10.
Text = r.Name,
11.
HasChildren = r.Children.Count > 0
12.
};
13.
if
(r.Children.Count > 0)
14.
{
15.
foreach
(var c
in
r.Children)
16.
{
17.
item.Items.Add(
new
DropDownTreeItem
18.
{
19.
Id = c.Id?.ToString(),
20.
Text = c.Name,
21.
HasChildren =
false
22.
});
23.
}
24.
}
25.
items.Add(item);
26.
}
27.
return
Json(items);
28.
}
But that doesn't really work, the autocomplete does not contain any items then, for some reason that also doesn't populate anything in the autocomplete (I get "no data found" even though there are items). From the examples I've seen, it seems that DropDownTreeItem needs to call the search method recursively to get its children and this doesn't work for me because my service already returns me all the relevant children based on my search string.
I've tried using the ToTreeDataSourceResult method like this:
1.
public
async Task<JsonResult> Search(
string
language,
string
searchString)
2.
{
3.
IReadOnlyCollection<MyDto> results = await _myService.Search(language, searchString);
4.
var tree = results.ToTreeDataSourceResult(
new
DataSourceRequest(), a => a.Id, a => a.IdParent);
5.
return
Json(tree.Data);
6.
}
that also doesn't populate anything in the autocomplete. (I get "no data found" even though the tree.Data has data).
I'm starting to think that this DropDownTree is not the right component and maybe I can achieve what I want with a simple AutoComplete and some styling ?
Hopefully my problem is clear enough with those details.
Any help would be greatly appreciated,
Thanks!