2012-02-21

Programmatically adding options to EPi CMS 6 R2 drop-down list property when using PageTypeBuilder 2.0

Since EPi CMS had property types with custom settings added I have found the drop-down list (EPiServer.SpecializedProperties.PropertyDropDownList) especially useful for allowing an editor to choose from a few different teaser content block appearances when creating teaser page types. The out-of-the-box approach is for an CmsAdmin or developer to manually add key-value pair type options in the CMS admin mode for the property but when using PageTypeBuilder there is a nice way of adding settings programmatically:



I implemented it in a way so that I can add a drop-down list using the attribute class PropertyDropDownListSettings like this:

[PageTypeProperty(
    EditCaption = "Layout",
    DefaultValue = "default",
    Required = true,
    SortOrder = 11,
    Type = typeof(EPiServer.SpecializedProperties.PropertyDropDownList))]
[PropertyDropDownListSettings(
    Settings = new string[]
    {
        "Default|default",
        "Compact|compact",
        "Video|video",
        "RSS Feed|rss",
        "Wide|wide"
    })]
public virtual string TeaserLayout { get; set; }

Attribute classes only accept primitive constants and arrays of primitives as parameters and I wanted to add one to many name-value pairs of <string, string>. I settled for a string array with pipe separated pairs and some old fashioned string handling in the UpdateSettings method. I only tested this lightly so the following may be subject to update:

using System;
using System.Text;
using EPiServer.Web.PropertyControls.PropertySettings;
using PageTypeBuilder;

public class PropertyDropDownListSettingsAttribute : Attribute, IUpdatePropertySettings<MultipleOptionsListSettings>
{
    //// { "Name|value", "Name|value2", "Name|value3" }
    public virtual string[] Settings { get; set; }

    public bool OverWriteExistingSettings
    {
        get
        {
            return true;
        }
    }

    public int GetSettingsHashCode(MultipleOptionsListSettings settings)
    {
        StringBuilder sb = new StringBuilder();

        foreach (string optionValue in settings.ListOptions.Values)
        {
            sb.Append(optionValue);
        }

        return sb.GetHashCode();
    }

    public void UpdateSettings(MultipleOptionsListSettings settings)
    {
        if (this.Settings != null)
        {
            foreach (string pair in this.Settings)
            {
                string[] splitPair = pair.Split('|');

                if (splitPair.Length >= 2 &&
                    !string.IsNullOrEmpty(splitPair[0]) &&
                    !string.IsNullOrEmpty(splitPair[1]))
                {
                    if (settings.ListOptions.ContainsKey(splitPair[0]))
                    {
                        settings.ListOptions[splitPair[0]] = splitPair[1];
                    }
                    else
                    {
                        settings.ListOptions.Add(splitPair[0], splitPair[1]);
                    }
                }
            }
        }
    }
}

As you can tell, this allows for adding new name-value pairs and updating values for existing names. It's still possible to add additional values in admin mode since UpdateSettings will not remove anything. If a name-value pair is removed in the page type definition class file, then that value must be deleted in admin mode since it will remain active until someone does so.

7 comments:

  1. Anonymous01 May, 2012

    Thanks!! This is great :) You should consider adding this to the episerver nuget repo.

    ReplyDelete
  2. Hans Hage09 July, 2012

    Works like a charm. Thank you for this - I second Anonymous's comment, this should be on the nuget repository.

    ReplyDelete
  3. this does not work to mine project. the values i defined in the attribute are not reflected to my dropdownlist.

    ReplyDelete
    Replies
    1. By the way, i'm using it to MultiplePropertyEntityProperty of ElencySolutions.MultiProperty

      Delete
  4. Hi, my project won't find the IUpdatePropertySettings interface.
    I have a reference to PageTypeBuilder version 2.0.50727.
    Any ideas?

    ReplyDelete
    Replies
    1. I can't remember having any other prerequisites than referencing PageTypeBuilder (I was also using 2.0.50727 as far as I can recall). Can't really come up with any reason why you shouldn't be able to find it and I don't have a lab environment using PTB anymore I'm afraid.

      As far as I can see it's supposed to be there: https://github.com/joelabrahamsson/Page-Type-Builder/blob/master/PageTypeBuilder/IUpdatePropertySettings.cs

      Sorry I couldn't help :)

      Delete
  5. Have you tried using this setting for multiple properties with different values?
    I tried doing the same this with enum, passing in its type and iterating on the values to build a collection for the dropdown.
    It worked like a charm when used on a single property, but once I added it to another property, passing in a different enum type, my EditTree started throwing exceptions..

    ReplyDelete