Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • tc 41 posts 62 karma points
    Jul 29, 2012 @ 18:48
    tc
    0

    Multi-Level Custom Trees in 4.7

    Hello! 
    I'm currently trying to create a custom tree and I'm running into trouble when trying to render a nodes children. After browsing various articles/posts I'm at this point: 

    public override void Render(ref XmlTree tree)
    {
      List<Node> articles = NodeUtil.GetAllNodesOfDocumentType(-1, "Promoter");
      Node article = articles.Where(p => p.CreatorID == UmbracoEnsuredPage.CurrentUser.Id).FirstOrDefault();
    
      if(promo != null)
      {
          var dNode = XmlTreeNode.Create(this);
          dNode.NodeID = article.Id.ToString();
          dNode.Text = article.Name;
          dNode.Icon = "doc.gif";
          dNode.Action = "javascript:openArticle(" + article.Id + ")";
          dNode.Source = article.Children.Count > 0 ? this.GetTreeServiceUrl("" + article.Id) : "";
          tree.Add(dNode);
      }
    }

    The code above gets the article belonging to the current user (for the sake of testing, each user only has one article at the moment). I then attempt to print out the children of this article but instead of getting the desired output, I get the follwowing:

    Article Name
    - Article Name
      - Article Name
       - Article Name

    Each time I expand a node, it just seems to render the same node, and goes on and on.

    I've seen other ways of using the treeservice, like:

    TreeService treeService = new TreeService(...);
    node
    .Source = treeService.GetServiceUrl();

    But I get an error saying there is no GetServiceUrl method that takes 0 arguments. I assume the method above was for earlier versions?

    Any help would be greatly appreciated! Thanks

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jul 30, 2012 @ 11:23
    Jeroen Breuer
    1

    Here is the part of the code I used for creating a multi level custom tree. I hope it helps.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Web;
    
    using Project.BLL.Default;
    using Project.BLL.Utilities;
    using Project.DAL.CollectionClasses;
    using Project.DAL.EntityClasses;
    using Project.General.Default;
    using Project.Presentation.Layer;
    using Project.WebApplication.Sections.Products.Category;
    using Project.WebApplication.Sections.Products.Product;
    using umbraco.cms.presentation.Trees;
    using umbraco.interfaces;
    using umbraco.IO;
    
    namespace Project.WebApplication.Sections.Articles
    {
        public class LoadProductsTree : BaseTree
        {
            private ControllerLayer _controllerLayer;
    
            #region Properties
    
            public ControllerLayer ControllerLayer
            {
                get
                {
                    if (_controllerLayer == null)
                    {
                        _controllerLayer = new ControllerLayer();
                    }
                    return _controllerLayer;
                }
            }
    
            #endregion
    
            public LoadProductsTree(string application)
                : base(application)
            {
            }
    
            protected override void CreateRootNodeActions(ref List<IAction> actions)
            {
                //Remove the default actions.
                actions.Clear();
            }
    
            protected override void CreateAllowedActions(ref List<IAction> actions)
            {
                //Remove the default actions.
                actions.Clear();
            }
    
            protected override void CreateRootNode(ref XmlTreeNode rootNode)
            {
                //Create the root node.
                rootNode.Icon = "database_table.png";
                rootNode.OpenIcon = "database_table.png";
                rootNode.NodeType = TreeAlias;
                rootNode.Text = "Categories";
                rootNode.NodeID = Constants.ROOTPATH;
                rootNode.Menu.Add(CreateCategoryAction.Instance);
                rootNode.Menu.Add(SortCategoryAction.Instance);
            }
    
            public override void Render(ref XmlTree tree)
            {
                //Check if the current tree is a product.
                string isProduct = HttpContext.Current.Request.QueryString["isProduct"];
    
                if (string.IsNullOrEmpty(isProduct))
                {
                    //Get all the categories which will be displayed.
                    CategoryCollection categoryCollection = ControllerLayer.GetCategories();
    
                    foreach (CategoryEntity categoryEntity in categoryCollection)
                    {
                        //Create the category node.
                        XmlTreeNode xNode = XmlTreeNode.Create(this);
                        xNode.NodeID = categoryEntity.CategoryId.ToString();
                        xNode.Text = categoryEntity.BackendName;
                        xNode.Action = string.Format("javascript:openCategoryDetails('{0}');", categoryEntity.CategoryId);
                        xNode.Icon = "table_multiple.png";
                        xNode.OpenIcon = "table_multiple.png";
                        xNode.Menu.Add(CreateProductAction.Instance);
                        xNode.Menu.Add(DeleteCategoryAction.Instance);
                        xNode.Menu.Add(SortProductAction.Instance);
                        if (ControllerLayer.HasProducts(categoryEntity.CategoryId))
                        {
                            //If the node has children show them.
                            xNode.HasChildren = true;
                            xNode.Source = string.Format(IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/tree.aspx?rnd={0}&id={1}&treeType={2}&contextMenu={3}&isDialog={4}&isProduct=true", Guid.NewGuid(), categoryEntity.CategoryId, TreeAlias, ShowContextMenu, IsDialog);
                        }
    
                        tree.treeCollection.Add(xNode);
                    }
                }
                else if (isProduct == "true")
                {
                    //Get the id of the category.
                    int categoryId = this.id;
    
                    //Get all the products which will be displayed.
                    ProductCollection productCollection = ControllerLayer.GetProducts(categoryId);
    
                    foreach (ProductEntity productEntity in productCollection)
                    {
                        //Create the product node.
                        XmlTreeNode xNode = XmlTreeNode.Create(this);
                        xNode.NodeID = productEntity.ProductId.ToString();
                        xNode.Text = productEntity.BackendName;
                        xNode.Action = string.Format("javascript:openProductDetails('{0}');", productEntity.ProductId);
                        xNode.Icon = "table_gear.png";
                        xNode.OpenIcon = "table_gear.png";
                        xNode.Menu.Add(DeleteProductAction.Instance);
                        tree.treeCollection.Add(xNode);
                    }
                }
            }
    
            public override void RenderJS(ref StringBuilder Javascript)
            {
                //Opens the category details page.
                Javascript.Append(
                                    @"
                            function openCategoryDetails(id) {
                                parent.right.document.location.href = '" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + @"/customSections/products/CategoryDetails.aspx?id=' + id;
                            }
                            ");
    
                //Opens the product details page.
                Javascript.Append(
                                    @"
                            function openProductDetails(id) {
                                parent.right.document.location.href = '" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + @"/customSections/products/ProductDetails.aspx?id=' + id;
                            }
                            ");
            }
        }
    }

    Jeroen

  • tc 41 posts 62 karma points
    Jul 31, 2012 @ 11:19
    tc
    0

    Hi Jeroen,
    Thanks for your response.

    Is the main part for rendering children this:

    xNode.Source=string.Format(IOHelper.ResolveUrl(SystemDirectories.Umbraco)+"/tree.aspx?rnd={0}&id={1}&treeType={2}&contextMenu={3}&isDialog={4}&isProduct=true",Guid.NewGuid(), categoryEntity.CategoryId,TreeAlias,ShowContextMenu,IsDialog); 
     
     
    Could you explain a bit more about this?
    Many Thanks,
     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jul 31, 2012 @ 11:38
    Jeroen Breuer
    0

    Yes xNode.Source is used to render children. When you try to open a child node "public override void Render(ref XmlTree tree)" is called again, but with different values. That's why I add "&isProduct=true" to the querystring and "&id={1}" is the id of the parent. It's a bit of a custom way and there are better ways to do it. This blog might help: http://www.robertgray.net.au/2011/5/27/creating-custom-multi-level-trees-in-umbraco.aspx

    Jeroen

  • tc 41 posts 62 karma points
    Jul 31, 2012 @ 17:44
    tc
    0

    Hi Jeroen,
    Thanks for that! Seems like it should do the trick. Im away from my computer for a few days then will give it a try!

    Cheers, 

Please Sign in or register to post replies

Write your reply to:

Draft