Auto-suggestions for properties in Optimizely CMS

Create auto suggestions for text properties in Optimizely CMS.
Add auto suggestions to your string property!

After developing in Episerver and Optimizely for nearly 13 years, I recently stumbled upon a feature that has been a part of Optimizely CMS for ages, yet many developers seem to be unaware of its existence. It's the remarkable auto-suggestion functionality for string properties within the CMS.

Typically, creating a dropdown list property on a page in Optimizely CMS involves using the SelectionFactory, which is highly effective. However, this limits the editor's options to the predetermined dropdown items. If the editor wants to be able to add their own alternatives to the predefined options, the most straightforward way to accomplish this is by leveraging the CMS's inbuilt auto-suggestion functionality instead.

All that's required is the creation of a SelectionQuery class that implements the ISelectionQuery interface, which should comprise a constructor and two methods:

1. The first essential piece of the puzzle is the constructor, where you can add your predefined list values. It is a process similar to using the SelectionFactory-interface.

public MyEditableSelectionQuery()
{
    _items = new[] {
    new SelectItem() { Text = string.Empty, Value = string.Empty },
    new SelectItem() { Text = "First option", Value = "1" },
    new SelectItem() { Text = "Second option", Value = "2" },
    new SelectItem() { Text = "Third option", Value = "3" },
    new SelectItem() { Text = "Fourth option", Value = "4" } };
}

Constructor for the SelectionQuery class.


2. Additionally, you'll need to create a method called "GetItems", which gets invoked whenever the editor begins typing, and the results will appear in Optimizely CMS as auto-complete functionality. In my implementation, the method recognizes items that contain what the editor types:

public IEnumerable GetItems(string query) => _items.Where(i => i.Text.ToLower().Contains(query.ToLower()));

For auto-complete functionality in the "dropdown".


3. Finally, you'll require the "GetItemByValue" method. As described by Optimizely, this method is called when initializing an editor with an existing value to obtain the corresponding text representation. In my example, if the string value stored in the database is "3", it will find the text "Third option" and display it to the editor:

public ISelectItem GetItemByValue(string value) => _items.FirstOrDefault(i => i.Value.Equals(value));

Method for mapping stored db values to predefined auto-suggestion text.


Putting them together, would make your SelectionQuery class look like this:

[ServiceConfiguration(typeof(ISelectionQuery))]
public class MyEditableSelectionQuery : ISelectionQuery
{
    private readonly SelectItem[] _items;

    public MyEditableSelectionQuery()
    {
        _items = new[] {
            new SelectItem() { Text = string.Empty, Value = string.Empty },
            new SelectItem() { Text = "First option", Value = "1" },
            new SelectItem() { Text = "Second option", Value = "2" },
            new SelectItem() { Text = "Third option", Value = "3" },
            new SelectItem() { Text = "Fourth option", Value = "4" } };
    }
    
    public IEnumerable<ISelectItem> GetItems(string query) => _items.Where(i => i.Text.StartsWith(query, StringComparison.OrdinalIgnoreCase));
    
    public ISelectItem GetItemByValue(string value) => _items.FirstOrDefault(i => i.Value.Equals(value));
}

The complete custom selection query class.


How to use it


For using this new SelectionQuery, all you have to do to use it on your page, is adding the AutoSuggestSelection attribute to your string property:

    [AutoSuggestSelection(typeof(MyEditableSelectionQuery), AllowCustomValues = true)]
    [Display(Name = "My Auto suggest selection property", GroupName = SystemTabNames.Content, Order = 200)]
    public virtual string MyEditableSelectionProperty { get; set; }

Page property with AutoSuggestSelection attribute.

Without the AllowCustomValues = true attribute, the editor wont be able to input own text, by default AllowCustomValues is set to false with means it will work like an ordinary dropdown property.

Then run your solution, and watch the result:

Animation of how this works in the editor.
How this works for the editor.

It's worth noting that this feature works for all Episerver CMS solutions above version 8 and also in Optimizely CMS 12.


While I've been developing EPi-solutions for years, I had somehow overlooked this feature until recently. I hope that by sharing my experience, others will start utilizing this feature sooner than I did. 😄