My requirements are such that on initial load, the tree is empty and a user can do a search which would then load the results into the treeview. Once the view is loaded, the user will navigate the tree with the expand functions. It's possible that the user searches for a result that is at an arbitrary depth in the tree (not a top-level node) so I query all nodes from the root down to the search result. I need help figuring out how to set this hierarchy of nodes into the tree correctly. Currently, only the top-level node displays with no expander.
The object to be displayed in tree:
public class LocationModel { public string Id { get; set; } public string ParentId { get; set; } public string Name { get; set; } public List<LocationModel> Children { get; set; } = new List<LocationModel>(); public bool HasChildren => true; }
The controller:
public JsonResult GetLocationHierarchy(string locationId){ if (string.IsNullOrEmpty(locationId)) return new JsonResult(); //string id; var results = new List<LocationModel>(); using (var ctx = _docStore.OpenSession()) { // recursively step up the tree, adding each node to the list while (!string.IsNullOrWhiteSpace(locationId)) { var thisNode = (from l in ctx.Query<Location>() where l.Id.Equals(locationId) select new LocationModel { Id = l.Id, Name = l.FriendlyName, ParentId = l.ParentId }).SingleOrDefault(); if (thisNode != null) { results.Add(thisNode); locationId = thisNode.ParentId; } else locationId = string.Empty; } } // set the children on the nodes foreach (var node in results) node.Children = results.Where(x => x.ParentId == node.Id).ToList(); //return only the top level node (hierachy is in place) return Json(results.Where(x=> x.ParentId == string.Empty).ToList(), JsonRequestBehavior.AllowGet);
The tree view:
<div id="treeview"> <div class="demo-section k-content"> @(Html.Kendo().TreeView() .Name("treeView") .LoadOnDemand(true) .DataTextField("Name") .Events(events => events .Select("onSelect") .Expand("onExpand") ) .DataSource(dataSource => dataSource .Model(m => { m.Id("Id"); m.Field("Name", typeof(string)); m.Children("Children"); m.HasChildren("HasChildren"); }) .Read(read => read .Action("GetLocationChildren", "Home", new { locationId = Model.SelectedLocation.Id }) ) ) ) </div> </div>
The search button method:
function onSearchButtonClick(e) { if ($("#SelectedLocation_Name").val() == "") { console.log("No SelectedLocation Name"); return; } var u = '@Url.Action("GetLocationHierarchy")'; $.post(u, { locationId: $("#SelectedLocation_Id").val() }, function (data) { console.log("onSearchButtonClick returned..."); var treeView = $("#treeView").data("kendoTreeView"); if (treeView == null) { console.log("treeView is null!"); return; } console.log(e); treeView.setDataSource(data); }); }
