Setting the Folder in the sitecore TreeList control

The TreeList field type allows you to specify many things through the “Source” property as detailed in Sitecore’s documentation (and here). However, one setting that (I feel) is missing is the ability to specify which tree node to start from. By default, you can set the DataSource property which, behind the scenes, sets the root node from which to start the tree. The tree then gets rendered and displays just the root node and its immediate children… but there’s no way for me to do things like:

  1. Expand the first sub-folder that contains the an item of type XYZ
  2. Perform a sitecore query to determine which decendant folder to expand to
  3. Expand the tree to a particular node depending on some attribute of the context item that i’m editing.

In my particular case, we had FacultyProfile items with a Department field (TreeList type). They wanted the Department field TreeList to be “context aware” and auto-expand to the appropriate part of the Department Lookup tree depending on the Site that the FacultyProfile item was in. My solution was to extend Sitecore’s TreeList type to add the necessary functionality as detailed below.

Taking a look at the inner workings of the TreeList type (thank you .NET Reflector), I found that the TreeList type uses the TreeviewEx control to render the tree. The TreeviewEx control uses a DataContext control to set the Root folder and the start Folder. After some more digging, trial & error I came up with the following extended data type (how to create an extended data type):

namespace Drexel.CustomTypes
{
    public class SmartTreeList : TreeList
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (this.ItemID != null)
            {
                var tree = (TreeviewEx)this.FindControl(this.ID + "_all");
                var dc = FindDataContext(this);
                var item = Sitecore.Context.ContentDatabase.GetItem(this.ItemID);

                var pipeArgs = new PreRenderSmartTreeListArgs(item, dc);
                CorePipeline.Run("PreRenderSmartTreeList", pipeArgs);

                if (!string.IsNullOrEmpty(pipeArgs.DataContext.Folder))
                {
                    // 'Select' the Folder item in addition to expanding it...
                    var i = item.Database.GetItem(pipeArgs.DataContext.Folder);
                    if (i != null)
                        tree.SetSelectedItem(i);
                }
            }
        }

        private DataContext FindDataContext(System.Web.UI.Control c)
        {
            DataContext dc = null;

            if (c is DataContext)
                dc = (DataContext)c;
            else
            {
                foreach (System.Web.UI.Control ctl in c.Controls)
                {
                    dc = FindDataContext(ctl);
                    if (dc != null)
                        break;
                }
            }

            return dc;
        }
    }
}

I decided to use a custom Sitecore pipeline for my SmartTreeList type. Here’s a great synopsis of how to create a custom pipeline. This allows me to apply different logic for determining the “Start Folder” depending on the context item. So, in the OnPreRender event, I find DataContext control and get a reference to the Context Item. Then I call my custom pipeline which only contains 1 pipeline processor: FacultyProfileDepartmentProcessor.

First, the pipeline code…

    interface IPreRenderSmartTreeListProcessor
    {
        void Process(PreRenderSmartTreeListArgs args);
    }

 

    public class PreRenderSmartTreeListArgs : PipelineArgs
    {
        public PreRenderSmartTreeListArgs(Item item, DataContext dc)
        {
            this.Item = item;
            this.DataContext = dc;
        }

        public Item Item { get; set; }
        public DataContext DataContext { get; set; }
    }

 

    public class FacultyProfileDepartmentProcessor : IPreRenderSmartTreeListProcessor
    {
        public void Process(PreRenderSmartTreeListArgs args)
        {
            if (args.Item != null && args.Item.TemplateName == "FacultyProfile")
            {
                // My logic to determine the correct Department node to open...
                // ...
                // ...
                args.DataContext.Folder = pathOrItemIdOfDepartmentItem;
            }
        }
    }

Then, add the configuration for the pipeline:

   ...
      <PreRenderSmartTreeList>
        <processor type="Drexel.Pipelines.PreRenderSmartTreeList.FacultyProfileDepartmentProcessor, Sitecore.Drexel.Pipelines" />
      </PreRenderSmartTreeList>
   ...

That’s it. Relatively simple… relatively extensible. Just the way I like it..

🙂

Advertisements

About Paul Martin

I enjoy rock climbing, playing guitar, writing code...
This entry was posted in Custom Component, Field Types, Sitecore, TreeList. Bookmark the permalink.

5 Responses to Setting the Folder in the sitecore TreeList control

  1. In tree list, How to show display name for any item?

    • Paul Martin says:

      The default behavior of the TreeList is to use each node item’s DisplayName. You set the DisplayName for a sitecore item by selecting the item in the Content Tree and setting the “Display Name” field in the “Appearance” section (make sure you’ve checked the ‘Standard Fields’ checkbox in the View tab of Content Editor first).

  2. Pingback: Displaying selected item paths in Treelist field | Paul's Sitecore Musings

  3. John West says:

    I tried this in OnLoad() after calling base.OnLoad (I don’t think you can do it before calling base.OnLoad() because that OnLoad() creates the data context). I only had to set DataContext.Folder; I did not have to call tree.SetSelectedItem().

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s