Custom ordered treelist

On a different blog platform, 3 years ago, I created the following entry, which I thought would be nice to have in my ‘own’ blog platform as well.

On a project I was working on recently all the banners were put into a common folder. In the common folder was a hierarchical structure, which would make it easier to find banners when I wanted to select them in my banners field. On the offside, if you have a lot of banners, it can become very difficult to find the one you want to change.

Current situation

In my case it would be sufficient if I could have the name of the parent item in front of the selected item.

To accomplish this, I needed to complete 3 tasks:

  1. Create a custom class that inherits the TreeList
  2. In the Core database, create the new field type
  3. Set our field type in the template

Create a custom class
This custom class needs to override the OnLoad method, since that calls the method we are actually interested in: RestoreState.

protected override void OnLoad(EventArgs args)
{
  base.OnLoad(args);
  Assert.ArgumentNotNull(args, "args");
  if (!Sitecore.Context.ClientPage.IsEvent)
  {
    this.RestoreState();
  }
}

Then we pretty much keep the original RestoreState the way it was as well, except for a few lines.

private void RestoreState()
{
  Listbox _listBox = (Listbox)FindControl(this.ID = "_selected");
  string[] strArray = this.Value.Split(new char[]{'|'});
  _listBox.Controls.Clear();
  if (strArray.Length > 0)
  {
    Database contentDatabase = Sitecore.Context.ContentDatabase;
    if (!string.IsNullOrEmpty(this.DatabaseName))
    {
      contentDatabase = Factory.GetDatabase(this.DatabaseName);
    }

    for (int i=0; i < strArray.Length; i++)
    {
      string str = strArray[i];
      if (!string.IsNullOrEmpty(str))
      {
        ListItem child = new ListItem();
        child.ID = Sitecore.Web.UI.HtmlControls.Control.GetUniqueID("I");
        _listBox.Controls.Add(child);
        child.Value = child.ID + "|"+ str;
        Item item = contentDatabase.GetItem(str);
        if (item != null)
        {
          child.Header = item.Parent.DisplayName + ":" + item.DisplayName;
        }
        else
        {
          child.Header = str + ' ' + Translate.Text("[Item not found]");
        }
      }
    }

    SheerResponse.Refresh(_listBox);
  }
}

Because the base.OnLoad() runs first, the listbox is already filled. To prevent it from containing double values, we need to clear it first. Then we run through the selected values again, putting the displayname of its parent in front.

Now, all we need to do is add the following to the web.config, in the <controlsources> node.

<source mode="on" namespace="CustomTreeList" assembly="CustomTreeList" prefix="MyProject" />

Create the field type

What I did here was duplicate the TreeList type in the Core database, and set the control field to what we just added in the web.config, followed by the classname.

Set the field type
In the template where we have the field, we can now select the Custom Treelist we just added.

If we then check the banner field again, we get the following:

Thank you for reading, I hope this blog helps you.

If you have any suggestions or a better way, please let me know.

As commented on the original post:

To cause links in this field type to appear in the links database, you may want to duplicate the existing treelist entry in the /App_Config/FieldTypes.config file, and change only the name attribute in the new line to match the name of your custom field type.

Advertisements

One thought on “Custom ordered treelist

  1. Thanks for the post. I think you have a typo in first statement of “RestoreState”. It should be

    Listbox _listBox = (Listbox)FindControl(this.ID + “_selected”);

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s