Hello, I am currently evaluating the Telerik control sets for use in a large project to start soon. I have a requirement where we will be building a treeview in our ASP.NET MVC controller code using TreeViewItemModel list and passing to the view. In the view razor code and/or javascript, is there a way to access the TreeViewItemModel as a user is selecting different nodes in the tree? Specifically, when building the TreeViewItemModel, I populate the .Text and .Id properties and I need to access these values to post back to my controller code to handle the selection changes. Is this possible? I need to quickly mock something up to demonstrate this.
Controller code to build the treeview contents is here:
public List<TreeViewItemModel> BuildTreeContents()
{
List<TreeViewItemModel> tree = new List<TreeViewItemModel>();
IQueryable<SupplierModel> suppliers = GetSuppliers();
IQueryable<ManagedOrgModel> managedOrgs = null;
IQueryable<ManagedLocationModel> locations = null;
TreeViewItemModel node = null;
List<TreeViewItemModel> orgs = null;
List<TreeViewItemModel> locs = null;
foreach (SupplierModel supplier in suppliers)
{
node = new TreeViewItemModel();
node.Text = supplier.SupplierName;
node.Id = supplier.SupplierID;
managedOrgs = GetManagedOrgs(supplier.ClientID, supplier.SupplierID);
orgs = new List<TreeViewItemModel>();
foreach (ManagedOrgModel managedOrg in managedOrgs)
{
TreeViewItemModel orgNode = new TreeViewItemModel();
orgNode.Text = managedOrg.ManagedOrgName;
orgNode.Id = managedOrg.ManagedOrgID;
locations = GetLocations(managedOrg.ClientID, managedOrg.SupplierID, managedOrg.ManagedOrgID);
locs = new List<TreeViewItemModel>();
foreach (ManagedLocationModel location in locations)
{
TreeViewItemModel locationNode = new TreeViewItemModel();
locationNode.Text = location.ManagedLocationName;
locationNode.Id = location.ManagedLocationID;
locs.Add(locationNode);
}
orgNode.Items = locs;
orgNode.HasChildren = true;
orgs.Add(orgNode);
}
node.Items = orgs;
node.HasChildren = true;
tree.Add(node);
}
return tree;
Thanks,
Doug Matulis
11 Answers, 1 is accepted
I am attaching an ASP.NET MVC solution, where a similar scenario to the one described is demosntrated (Retrieving the data item for the currently selected TreeView node).
The desired behavior can be easily achieved as follows:
1) Subscribe to the TreeView select event:
@(Html.Kendo().TreeView()
.Name(
"treeview"
)
...
.Events(ev => ev.Select(
"onTreeViewselectNode"
))
)
2) Retrieve the widget instance (e.sender) and use the TreeView's dataItem() method to retrieve the to retrieve the data item to which the clicked node is bound to:
<script>
function
onTreeViewselectNode(e) {
var
dataItem = e.sender.dataItem(e.node);
console.log(dataItem);
}
</script>
Then, you should be able to send an ajax request to a controller action method an process the data on the server as per the project requirements.
Regards,
Dimitar
Progress Telerik
Hello Dimitar,
Thanks for getting back to me. It's strange, I had the same code in my .cshtml file as your sample (see snippet below) and yet when I debug my code e.node is undefined and yours works. I went through both projects and the only difference is I am building my tree contents in my controller code based on database contents and using TreeViewItemModel objects in a tree hierarchy and passing the model to the view via the viewbag. Tree renders and works fine in the view at runtime, but as noted, e.node is undefined in the event handler. See snippet:
Controller Code:
public ActionResult POSCreated()
{
ViewBag.Message = "POs Created test page";
IEnumerable<TreeViewItemModel> tree = savvy.GetTreeContents();
ViewBag.Tree = tree;
return View();
}
---------------------------------------------------------------------------
.cshtml code:
@{
ViewBag.Title = "POSCreated";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container-fluid placeholders">
<div class="row">
<div class="col-xs-4 col-md-2 placeholder">
<h2>POSCreated</h2>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3 k-content">
@(Html.Kendo().TreeView()
.Name("navTreeView")
.BindTo((List<TreeViewItemModel>)ViewBag.Tree)
.Events(handler => handler
.Change("onTreeNodeSelected")
)
)
</div>
<div class="col-md-9">
</div>
</div>
</div>
<script>
function onTreeNodeSelected(e) {
var dataitem = e.sender.dataItem(e.node);
debugger;
}
</script>
I am attaching a modified version of the previous project, where the TreeView binding is updated as per your example. With it, the change event works as expected. Please inspect the sample and try to integrate the same approach in your application.
In case the issue continues to persist, please modify the above solution, so that the issue is reproduced and send it back to us for additional review. This way, I will be able to troubleshoot it locally and determine if the observed behavior is cause by environment or widget configuration and advise you further.
Regards,
Dimitar
Progress Telerik
Hi Dimitar:
I attached the project I have been working with where the e.node is undefined when a node is selected and handled in the javascript event handler. See the POs Created cshtml file and relevant code in the Home controller. All dependencies on our database have been removed.
Thanks,
Doug
Dimitar, Last attachment failed, trying again.... Failed once more.
I take a look at your last attachment and see if I can get something to work.
Thanks,
Doug
Hello Dimitar:
Ok, I'm stupid or blind, maybe both. I found the issue and I don't know how I kept missing it. I was using the Change event instead of the Select event in the tree. Sorry to have taken your time.
Much Thanks,
Doug
I am glad to hear that the issue that you were facing is now successfully resolved.
Regards,
Dimitar
Progress Telerik
Is that the only way to implement the TreeView control? All the free ones do the same thing: use a flat model with ID, ParentID, etc.
But I have a nested group join (see below) that is already in hierarchical form. Why can't I just feed it to the control? Do I have to convert the joins to a flat model?
Thanks,
Jay
var listGAA2 = (from GE in db.GENRE
join AL in db.ALBUM on GE.GENRE_ID equals AL.GENRE_ID into albumgenre
orderby GE.NAME
select new
{
GenreID = GE.GENRE_ID,
GenreName = GE.NAME,
albums = from AL in albumgenre
join AR in db.ARTIST on AL.ARTIST_ID equals AR.ARTIST_ID into albumartist
orderby AL.NAME
select new
{
AlbumID = AL.ALBUM_ID,
AlbumName = AL.NAME,
artist = from AR in albumartist
select new
{
ArtistID = AR.ARTIST_ID,
ArtistName = AR.NAME
}
}
}).ToList();
There is an existing demo, where a similar scenario to the one described is demonstrated (Binding TreeView widget to different parent nodes with an unknown number of records):
Form the above example, you will notice that the widget is bound to Categories > Products > OrderDetails. When a node is expanded, an ajax request is being issued to the server to retrieve the corresponding parent-child items, which are then displayed in the TreeView. From the above example, you could review the widget configuration and also inspect the service implementation in this GitHub repository.
Regards,
Dimitar
Progress Telerik
Thank you, Dimitar, for your response. I do appreciate your time.
Unfortunately, I am not a JavaScript developer and I have no clue how to download the project you linked to from Git (there is no "download" button that I saw).
I'm just a WINS tech stack backend developer. But it appears that I have to be a javascript developer to use your product.
I'm only in a trial period and will ask Support for assistance with this particular bit of rocket science.
In general, the linked GitHub repository contains the implementation of the service that is used in the Kendo UI official demos and I have linked it just for a reference. In case you would like to download it, you could do so by navigating to the root of the Project and then clicking on the 'Clone or download' button. However, for learning purposes, I would suggest using the Sample Application that is distributed with the Telerik UI for ASP.NET MVC package.
If you have installed the Telerik UI for ASP.NET MVC package from the .msi executable that is available for download from your Telerik profile, then you should be able to run the Sample Application that is a copy of the demos site. Check out the following guide on how to start the application with Visual Studio:
With the above application running, you should be able to navigate to the TreeView Odata Binding Demo and inspect the code needed to configure it from the Sample Application solution.
Regards,
Dimitar
Progress Telerik