EPiServer Dropdown CheckList Property

Posted on August 28, 2010 by Frederik Vig in ASP.NET, EPiServer

Today I wanted to create a custom property in EPiServer that uses a dropdown list where the user can select multiple options. In HTML you have the select element which when having the attribute multiple=”multiple” actually does what I want, but can get quite long if you have many options to choose from. So I ended up creating my own with the help of the jQuery plugin Dropdown Check List which transforms a HTML select element to a dropdown check list.

I started by creating four classes: CategorySettings.cs, CategorySettingsUI.cs, PropertyDropdownCheckList.cs, and PropertyDropdownCheckListControl.cs. The two classes for the settings I just copied from my previous post on custom settings, they’re used for setting a root EPiServer category to get the options from (easier to maintain than storing them in appSettings for instance).

The code for PropertyDropdownCheckList.cs and PropertyDropdownCheckListControl.cs

using System;
using EPiServer.Core;
using EPiServer.Core.PropertySettings;
using EPiServer.PlugIn;
 
namespace EPiServer.Templates.Public.CustomProperty
{
    [Serializable]
    [PageDefinitionTypePlugIn]
    [PropertySettings(typeof (CategorySettings), true)]
    public class PropertyDropdownCheckList : PropertyString
    {
        public override IPropertyControl CreatePropertyControl()
        {
            return new PropertyDropdownCheckListControl();
        }
    }
}
using System.Web.UI.WebControls;
using EPiServer.DataAbstraction;
using EPiServer.Web.PropertyControls;
 
namespace EPiServer.Templates.Public.CustomProperty
{
    public class PropertyDropdownCheckListControl : PropertyTextBoxControlBase
    {
        protected System.Web.UI.WebControls.ListBox listBox;
 
        public override bool SupportsOnPageEdit
        {
            get { return false; }
        }
 
        public PropertyDropdownCheckList CategoryCheckBoxList
        {
            get { return PropertyData as PropertyDropdownCheckList; }
        }
 
        public override void CreateEditControls()
        {
            this.listBox = new ListBox();
            listBox.SelectionMode = ListSelectionMode.Multiple;
 
            CategorySettings settings = (CategorySettings) base.PropertyData.GetSetting(typeof (CategorySettings));
 
            Category mainCategory = Category.Find(settings.RootCategory);
            var values = CategoryCheckBoxList.Value as string;
 
            foreach (Category c in mainCategory.Categories)
            {
                ListItem li = new ListItem(c.LocalizedDescription, c.Name);
 
                if (!string.IsNullOrEmpty(values))
                {
                    foreach (string value in values.Trim().Split('|'))
                    {
                        if (value == c.Name)
                        {
                            li.Selected = true;
                        }
                    }
                }
 
                listBox.Items.Add(li);
            }
 
            ApplyControlAttributes(listBox);
            Controls.Add(listBox);
        }
 
        public override void ApplyEditChanges()
        {
            string values = string.Empty;
            foreach (ListItem listItem in this.listBox.Items)
            {
                if (listItem.Selected)
                {
                    values += listItem.Value + "|";
                }
            }
 
            SetValue(values);
        }
    }
}

I now ended up being able to choose a root category under my properties settings and rendering a HTML select element with the attribute multiple set to multiple.

This is how it now looked for me in EPiServer edit mode.
Multiple select element in EPiServer edit mode

Next thing was adding the jQuery plugin and implementing the code – which also was very straight forward. I added a new method for registering my resources (CSS and JavaScript files), and a helper method for my CSS files. Here’s how PropertyDropdownCheckListControl.cs ended up looking.

using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using EPiServer.DataAbstraction;
using EPiServer.Web.PropertyControls;
 
namespace EPiServer.Templates.Public.CustomProperty
{
    public class PropertyDropdownCheckListControl : PropertyTextBoxControlBase
    {
        protected System.Web.UI.WebControls.ListBox listBox;
 
        public override bool SupportsOnPageEdit
        {
            get { return false; }
        }
 
        public PropertyDropdownCheckList CategoryCheckBoxList
        {
            get { return PropertyData as PropertyDropdownCheckList; }
        }
 
        public override void CreateEditControls()
        {
            this.listBox = new ListBox();
            listBox.SelectionMode = ListSelectionMode.Multiple;
            listBox.ID = "DropdownCheckList";
 
            CategorySettings settings = (CategorySettings) base.PropertyData.GetSetting(typeof (CategorySettings));
 
            Category mainCategory = Category.Find(settings.RootCategory);
            var values = CategoryCheckBoxList.Value as string;
 
            foreach (Category c in mainCategory.Categories)
            {
                ListItem li = new ListItem(c.LocalizedDescription, c.Name);
 
                if (!string.IsNullOrEmpty(values))
                {
                    foreach (string value in values.Trim().Split('|'))
                    {
                        if (value == c.Name)
                        {
                            li.Selected = true;
                        }
                    }
                }
 
                listBox.Items.Add(li);
            }
 
            ApplyControlAttributes(listBox);
 
            Controls.Add(listBox);
 
            this.RegisterResources();
        }
 
        public override void ApplyEditChanges()
        {
            string values = string.Empty;
            foreach (ListItem listItem in this.listBox.Items)
            {
                if (listItem.Selected)
                {
                    values += listItem.Value + "|";
                }
            }
 
            SetValue(values);
        }
 
        private void RegisterResources()
        {
            Page.Header.Controls.Add(CreateCssLink("~/templates/public/customproperty/ui.dropdownchecklist.css", "screen"));
 
            if (!Page.ClientScript.IsClientScriptIncludeRegistered("jQuery"))
            {
                Page.ClientScript.RegisterClientScriptInclude("jQuery", "/templates/public/customproperty/jquery-min.js");
            }
 
            if (!Page.ClientScript.IsClientScriptIncludeRegistered("uicore"))
            {
                Page.ClientScript.RegisterClientScriptInclude("uicore", "/templates/public/customproperty/ui.core-min.js");
            }
 
            if (!Page.ClientScript.IsClientScriptIncludeRegistered("dropdownchecklist"))
            {
                Page.ClientScript.RegisterClientScriptInclude("dropdownchecklist", "/templates/public/customproperty/ui.dropdownchecklist-min.js");
            }
 
            Page.ClientScript.RegisterStartupScript(GetType(), "dropdownchecklist-setup" + this.GetHashCode(), string.Format("$('#{0}').dropdownchecklist();", listBox.ClientID), true);
        }
 
        public static HtmlLink CreateCssLink(string cssFilePath, string media)
        {
            var link = new HtmlLink();
            link.Attributes.Add("type", "text/css");
            link.Attributes.Add("rel", "stylesheet");
            link.Href = link.ResolveUrl(cssFilePath);
            if (string.IsNullOrEmpty(media))
            {
                media = "all";
            }
 
            link.Attributes.Add("media", media);
            return link;
        }
    }
}

And the result in edit mode:
Dropdown Check List in EPiServer edit mode

There are a ton of things you can do with the plugin to customize it even more. Check out the demo page for some more samples.

Download the code

Related Posts: