The selector property type adds the option to create properties where the editor can choose from a list of options which are provided through code.

The options can be represented by a title, a description and an image. The dropdown presentation will depend on what values are provided. In the sample below the first selector has a title, the second title and description and the third title, description and image:

Selector property in Kaliko CMS

Selectors can be based on strings, ints, enums or any other compatible type. To declare a selector property create a virtual property of the type SelectorProperty<T> where T is the type you wish to use. The property also needs to be decorated with a SelectorProperty-attribute where the second parameter points to a SelectorFactory<T> that is used to provide the options for the selector. The sample code below shows three selector properties using enum, int and string as option formats:

namespace DemoSite.Models {
    using KalikoCMS.Attributes;
    using KalikoCMS.Core;
    using KalikoCMS.PropertyType;

    [PageType("ArticlePage", "Article page")]
    public class ArticlePage : CmsPage {
        [SelectorProperty("Simple selector", typeof(MyEnumFactory))]
        public virtual SelectorProperty<MyEnum> SomeEnum { get; set; }

        [SelectorProperty("Text selector", typeof(MyNumberFactory))]
        public virtual SelectorProperty<int> SomeNumber { get; set; }

        [SelectorProperty("Image selector", typeof(MyStringFactory))]
        public virtual SelectorProperty<string> SomeString { get; set; }
    }
}

The selected value is available typed through the Value property, for instance SomeEnum.Value is the selected MyEnum and SomeString.Value is the selected string value.

Creating a selector factory

To create a selector factory to provide the options add a new class which inherits from SelectorFactory<T> where T is the type your selector property uses.

Implement the Options property in the new factory class and let it return a list of SelectorItem<T> where each option has a value and a title, with optional description and paths to images depending on how you want the selector to be presented (see image above).

A simple numeric selector:

namespace DemoSite.Models {
    using System.Collections.Generic;
    using KalikoCMS.PropertyType;

    public class NumberFactory : SelectorFactory<int> {
        public override IEnumerable<SelectorItem<int>> Options {
            get {
                return new List<SelectorItem<int>>() {
                    new SelectorItem<int>() {Value = 1, Title = "First"},
                    new SelectorItem<int>() {Value = 2, Title = "Second"},
                    new SelectorItem<int>() {Value = 3, Title = "Third"}
                };
            }
        }
    }
}

The same factory but expanded to show description and a thumbnail:

namespace DemoSite.Models {
    using System.Collections.Generic;
    using KalikoCMS.PropertyType;

    public class NumberFactory : SelectorFactory<int> {
        public override IEnumerable<SelectorItem<int>> Options {
            get {
                return new List<SelectorItem<int>>() {
                    new SelectorItem<int>() {Value = 1, Title = "First", Description = "The very first item", PreviewImage = "/img/first.png"},
                    new SelectorItem<int>() {Value = 2, Title = "Second", Description = "The difficult second item", PreviewImage = "/img/second.png"},
                    new SelectorItem<int>() {Value = 3, Title = "Third", Description = "The third and last item", PreviewImage = "/img/third.png"}
                };
            }
        }
    }
}

Thumbnails won't be scaled so they need to be provided in the size you want to use.

The selector factories can also be dynamic, like this sample that creates the options based on folder content:

namespace Sample.Core.Factories {
    using System.Collections.Generic;
    using System.IO;
    using System.Web;
    using KalikoCMS.PropertyType;

    public class ThemeSelectorFactory : SelectorFactory<string> {
        public override IEnumerable<SelectorItem<string>> Options {
            get {
                var items = new List<SelectorItem<string>>();

                var directories = Directory.GetDirectories(HttpContext.Current.Server.MapPath("~/themes/"));
                foreach (var path in directories) {
                    var directory = Path.GetFileName(path);
                    items.Add(new SelectorItem<string> { Title = directory, Value = directory });
                }

                return items;
            }
        }
    }
}