How can I find out when the treeview has finished loading?

4 posts, 1 answers
  1. Veronique
    Veronique avatar
    3 posts
    Member since:
    Apr 2012

    Posted 17 Aug 2012 Link to this post

    This is my Kendo treeview definition:

    @(Html.Kendo().TreeView()
            .Name("CollectionsheetTree")
            .DataSource(dataSource => dataSource
                .Read(read => read
                    .Action("_getProjectCollectionsheetTree2", "Project", new { projectId = _projectId })            )
            )
     .HtmlAttributes(new { style = "height: 200px; overflow: auto; " })
     .DragAndDrop(!Model.IsReadOnly)
    )

    When the ajax call has completed, I need to run some processing on the treeview to style it (e.g. change the text font).

    I put the code  in the $(document).ready as suggetsed by the Kendo documentation:

     $(document).ready(function () {
         var treeView = $("#CollectionsheetTree").data("kendoTreeView");

                treeView.find(".k-in").each(function() {
                    var element = $(this),
                        data = element.find('> .data');

                    if (data.length) {
                        //element.css('background-color', '#aabbcc' );
                        element.addClass("treeviewNode");
                        data.remove();
                    }
                });
    });


    But the execution fails over on this line:
      treeView.find(".k-in").each(function() {

    The error message says:
    Microsoft JScript runtime error: Unable to get value of the property 'find': object is null or undefined

    I think it is because when the $(document).ready is executed the treeview is still being constructed.
    On the Telerik treeview control there is a OnDataBound event that can be used to ensure that a function is run only after the treeview has been fully initialised.

    How can I ensure that the Kendo treeview has been initialised before calling the styling function on it?

    For completeness, here is the controller method:

     

             public ActionResult _getProjectCollectionsheetTree2(kendoTreeviewItem node,   int? projectId)
             {
                 var nodes = new List<kendoTreeviewItem>();
                 List<DofSurvey> list;
                 _dofSurvey.EnrolInUnitOfWork(_unitOfWork);
                
                 int collectionSheetId;
                 int.TryParse(node.id, out collectionSheetId);

                 if (node.id == null)
                 {
                     list = _dofSurvey.FindBy(f => f.ParentSurveyId == null & f.ProjectId == projectId, "Survey").ToList();
                 }
                 else
                 {
                     list = _dofSurvey.FindBy(f => f.ParentSurveyId == collectionSheetId & f.ProjectId == projectId, "Survey").ToList();
                 }

                 list.ForEach(cs =>
                 {
                     var d = new kendoTreeviewItem
                     {
                         id = cs.SurveyId.ToString(),
                         text = cs.Survey.Title + "<span class='data'></span>",
                         hasChildren = cs.ChildSurveys.Any()
                     };
                     nodes.Add(d);
                 });
                 return Json(nodes, JsonRequestBehavior.AllowGet);
             }


  2. Answer
    Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 21 Aug 2012 Link to this post

    Hi Veronique,

    Our TreeView client object $("#CollectionsheetTree").data("kendoTreeView") does not have such method find. Probably you want to use just a jQuery object (which wraps the TreeView element) :

    • $("#CollectionsheetTree").find()

    Regarding the load event of the TreeView when using Ajax to load the data - we have introduced a new event (requestEnd) in the latest internal build, which can be used in your case.

    As a commercial license owner you have access to the latest internal build - to download it please log on with your account at Telerik site and follow these steps:

    • Click on "Manage products" button, and select "Latest Internal Builds" from the drop-down menu
    • As a product, please select "Kendo UI Complete for ASP.NET MVC"
    • As a major version - please select latest one (currently 2012.2)
    • Download the latest available build (currently "kendoui.aspnetmvc.2012.2.815.commercial")


    Kind Regards, Vladimir Iliev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Veronique
    Veronique avatar
    3 posts
    Member since:
    Apr 2012

    Posted 22 Aug 2012 Link to this post

    Yes you are correct.  I meant to use the jQuery object on the treeview element. Thank you. 
    Otherwise, I downloaded the internal build to get the new requestEnd datasource event. 
    I am attempting to use this event in order to load the full treeview when the page is loaded.  Currently only the top level nodes are added to the treeview.  I tried a few things with the requestEnd event but when the event handler is executed, the new top level nodes are not in the dom yet.  Consequently,  treeview.expand(".k-item");   does nothing.
     
             function requestEndHandler() {
                 var treeviewElement = $("#CollectionsheetTree");
                 var count = 0;
                 treeviewElement.find(".k-item").each(function() {
                     count = count +1;
                 });
          //after the loop, count is 0
     
                var treeview = $("#CollectionsheetTree").data("kendoTreeView");
                 treeview.expand(".k-item");  //does nothing
     
            }
     Could you please tell me what I need to do to load the whole tree view automatically when the page is being shown?
     
    Interestingly, expending one of the top level nodes (by clicking with the mouse on the triangle next to it) triggers the loading of the treeview in full.
     
    If you need, this is the definition of the treeview:
                             @(Html.Kendo().TreeView()
                                 .Name("CollectionsheetTree")
                                 .DataSource(dataSource => dataSource
                                     .Read(read => read
                                         .Action("_getProjectCollectionsheetTreeKendo", "Project", new { projectId = _projectId })
                                         ).Events(e => e.RequestEnd("requestEndHandler"))
                                 )
                                 .ExpandAll(true)
                                 .DataTextField("Text")
                             )
     
    This is the current version of the controller method:
           public ActionResult _getProjectCollectionsheetTreeKendo(int? id, int? projectId)
              {
                  var nodes = new List<object>();
                  List<DofSurvey> list;
                  _dofSurvey.EnrolInUnitOfWork(_unitOfWork);
                 
                 list = _dofSurvey.FindBy(f => (id.HasValue ? f.ParentSurveyId == id : f.ParentSurveyId == null) & f.ProjectId == projectId, "Survey").ToList();
                  list.ForEach(cs =>
                  {
                      var d = new {
                          id = cs.SurveyId.ToString(),
                          Text = cs.Survey.Title,
                          hasChildren = cs.ChildSurveys.Any(),
                          Expanded = true
                      };
                     nodes.Add(d);
                  });
                  return Json(nodes, JsonRequestBehavior.AllowGet);
              }
     
    Thank you in advance for your help.
  5. Veronique
    Veronique avatar
    3 posts
    Member since:
    Apr 2012

    Posted 22 Aug 2012 Link to this post

    The solution is simply to add the .LoadOnDemand(false), in the treeview definition as shown below:
                            @(Html.Kendo().TreeView()
                                .Name("CollectionsheetTree")
                                .DataSource(dataSource => dataSource
                                    .Read(read => read
                                        .Action("_getProjectCollectionsheetTreeKendo", "Project", new { projectId = _projectId })
                                        ).Events(e => e.RequestEnd("requestEndHandler"))
                                )
                                .HtmlAttributes(new { style = "height: 200px; overflow: auto; " })
                                .ExpandAll(true)
                                .DataTextField("Text")
                                .LoadOnDemand(false)
                                .Animation(false)
                            )

    Just in case someone wants to see all the 'bits', here they are:
    View:
            function requestEndHandler() {
                var treeview = $("#CollectionsheetTree").data("kendoTreeView");
                treeview.expand(".k-item"); 
            }

    Controller:
             public ActionResult _getProjectCollectionsheetTreeKendo(int? id, int? projectId)
             {
                 var nodes = new List<object>();
                 List<DofSurvey> list;
                 _dofSurvey.EnrolInUnitOfWork(_unitOfWork);
                
                 list = _dofSurvey.FindBy(f => (id.HasValue ? f.ParentSurveyId == id : f.ParentSurveyId == null) & f.ProjectId == projectId, "Survey").ToList();
                 list.ForEach(cs =>
                 {
                     var d = new {
                         id = cs.SurveyId.ToString(),
                         Text = cs.Survey.Title,
                         hasChildren = cs.ChildSurveys.Any(),
                         Expanded = true
                     };
                    nodes.Add(d);
                 });
                 return Json(nodes, JsonRequestBehavior.AllowGet);
             }

     



Back to Top
UI for ASP.NET MVC is VS 2017 Ready