---
title: Using a dynamic data source with selector components
related:
  - https://docs.kentico.com/13/developing-websites/form-builder-development/assigning-editing-components-to-properties.md
  - https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api.md
  - https://docs.kentico.com/13/developing-websites/retrieving-content.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

In some instances, selector form components may benefit from a dynamic source of data. For example, if you need to enable selection from a list of objects, pages, custom table items, or other volatile data.

## Connecting a drop-down list to a dynamic data source

The following example demonstrates how to connect a drop-down list form component to a dynamic data source:

1. Open your project in Visual Studio.

2. Create a new [form component](https://docs.kentico.com/13/developing-websites/form-builder-development/developing-form-components.md), and register it in the system.

3. In the model class:

   1. Inherit from **SelectorFormComponent**.
   2. Override the **IEnumerable GetHtmlOptions** method and implement your data retrieval logic.
   3. (Optional) [Cache](https://docs.kentico.com/13/configuring-xperience/configuring-caching/caching-on-mvc-sites.md) the results of the operation.

   ```csharp title="CustomDropDownComponent.cs"

   using System.Linq;
   using System.Collections.Generic;

   using CMS.DocumentEngine;

   using Kentico.Forms.Web.Mvc;
   using Kentico.Web.Mvc;

   using LearningKit.FormBuilder.FormComponents;
   using LearningKit.FormBuilder.FormComponentProperties;

   [assembly: RegisterFormComponent(CustomDropDownComponent.IDENTIFIER, typeof(CustomDropDownComponent), "Drop-down with custom data", IconClass = "icon-menu")]

   namespace LearningKit.FormBuilder.FormComponents
   {
       public class CustomDropDownComponent : SelectorFormComponent<CustomDropDownComponentProperties>
       {
           public const string IDENTIFIER = "CustomDropDownComponent";

           // Retrieves data to be displayed in the selector
           protected override IEnumerable<HtmlOptionItem> GetHtmlOptions()
           {
               // Perform data retrieval operations here
               // The following example retrieves all pages of the 'DancingGoatMvc.Article' page type 
               // located under the 'Articles' section of the Dancing Goat sample website
               DocumentQuery query = DocumentHelper.GetDocuments("DancingGoatMvc.Article")
                                   .Path("/Articles/", PathTypeEnum.Children)
                                   .Columns("DocumentName", "DocumentGUID")
                                   .OnSite("DancingGoatMvc")
                                   .Culture("en-us")
                                   .LatestVersion();

               var sampleData = query.ToList().Select(x => new { Name = x.DocumentName,
                                                                   Guid = x.DocumentGUID.ToString() });

               // Iterates over retrieved data and transforms it into SelectListItems
               foreach (var item in sampleData)
               {
                   var listItem = new HtmlOptionItem()
                   {
                       Value = item.Guid,
                       Text = item.Name
                   };

                   yield return listItem;
               }
           }
       }
   }

   ```

4. In the properties class, inherit from **SelectorProperties**. Optionally, you can implement additional properties required for further customization.

   ```csharp title="CustomDropDownComponentProperties.cs"

   using Kentico.Forms.Web.Mvc;

   namespace LearningKit.FormBuilder.FormComponentProperties
   {
       public class CustomDropDownComponentProperties : SelectorProperties
       {
           // Implement any required custom properties here
       }
   }

   ```

5. Create a new _\_CustomDropDownComponent_ view under _\~/Views/Shared/FormComponents_ that renders a drop-down list populated with the retrieved data. Use the **ToSelectListItems** extension method (_Kentico.Forms.Web.Mvc_ namespace) to transform the collection of **HtmlOptionItems** into **SelectListItems**.

   ```csharp title="_CustomDropDownComponent.cshtml"

   @using Kentico.Web.Mvc
   @using Kentico.Forms.Web.Mvc
   @using LearningKit.FormBuilder.FormComponents

   @model CustomDropDownComponent

   @{
       var htmlAttributes = ViewData.Kentico().GetEditorHtmlAttributes();
   }

   @* Invoking a Get operation on the component's 'Items' property executes the GetItems method. *@
   @Html.DropDownListFor(x => x.SelectedValue, Model.HtmlOptions.ToSelectListItems(), null, htmlAttributes)

   ```

   The **SelectedValue** and **HtmlOptions** properties, inherited from _SelectorFormComponent_, respectively hold the value selected by a user, and the list of items to be displayed in the drop-down list.

The form component dynamically retrieves the specified data when instantiated and populates the corresponding drop-down selector.
