How do I make a dropdown's values dependent on the selection of another dropdown in Optimizely CMS?

  • Page Owner: Not Set
  • Last Reviewed: 2025-07-10

I have two dropdowns. The values available to be selected in the second dropdown depend on what value was selected in the first dropdown. How do I do this?


Answer

You can read the page's content via metadata?.Parent.Model. For example:

    [ContentType(
        DisplayName = "General Page",
        GUID = "62041A64-62FC-45C6-A375-9DAF13E8E52B",
        Description = "The General Page acts as a basic page for text and layouts.")]
    [ContentIcon(FontAwesomeIcons.FileLines, FontAwesomeIconStyle.Regular)]
    [ContentImage(FontAwesomeIcons.FileLines, FontAwesomeIconStyle.Regular)]
    public class GeneralPage : BasePage
    {
        // Example: the `Product` list changes based on the `ProductLine` selection.
        // Each property has it's own selection factory
        // Because `Product` depends on the `ProductLine` property value, we use `[ReloadOnChange]`
        // to force the admin UI to update w/ new values when the selection is changed.
        [ReloadOnChange] 
        [SelectOne(SelectionFactoryType = typeof(ProductLineSelectionFactory))]
        public virtual string ProductLine { get; set; } = "LawnMowers";

        [SelectOne(SelectionFactoryType = typeof(ProductSelectionFactory))]
        public virtual string Product { get; set; } = "";

    }

    public class ProductLineSelectionFactory : ISelectionFactory
    {
        public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
        {
            yield return new SelectItem { Text = "Lawn Mowers", Value = "LawnMowers" };
            yield return new SelectItem { Text = "Sprinklers", Value = "Sprinklers" };
        }
    }


    public class ProductSelectionFactory : ISelectionFactory
    {
        public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
        {
            // A default non-selection value.
            yield return new SelectItem { Text = "", Value = "" };

            // Get the value of the current page and return the correct values
            // depending on the `ProductLine` selection.
            if (metadata?.Parent.Model is GeneralPage generalPage)
            {
                switch (generalPage.ProductLine)
                {
                    case "LawnMowers":
                        yield return new SelectItem { Text = "Lawn Mower 1", Value = "Mower1" };
                        yield return new SelectItem { Text = "Lawn Mower 2", Value = "Mower2" };
                        break;
                    case "Sprinklers":
                        yield return new SelectItem { Text = "Sprinkler 1", Value = "Sprinkler1" };
                        yield return new SelectItem { Text = "Sprinkler 2", Value = "Sprinkler2" };
                        break;
                }
            }
            
        }
    }

Use [ReloadOnChange] to force the editorial interface to update when the selection changes.