How To Create a Dropdown List or Checkbox Control For Editors Populated By PageTypes or Enums

A very frequent requirement on projects is to give content editors the ability to pick from a list of ‘things’.  This list is usually either a drop-down or check-box list.  In the majority of situations, the data required to populate a drop down list or check box list is populated from either page types or enum.  In EpiWord this data population can be achieved by a thing called a selection factory

What is a Selection Factory?

We have a project manager on our project who learned the phrase” selection factory”.  His definition is interchangeable with a drop-down picker and for all purposes this is a good enough definition for the majority of cases.

When you start to work with a selection factory, you will get very familiar within the SelectOne and SelectMany attribute.  When you decorate one of your page or block properties with a SelectOne or SelectMany attribute, you will also need to provide a data source to populate it.  This data source is the selection factory.

A SelectOne will give your content editors a single selection control and a SelectMany will provide a multiple selection option.  Each property requires a SelectionFactoryType to be included.  This is where you will need to create some custom code to pull back the data you care about.

To create a selection factory you’ll need to create a class implementing the ISelectionFactory interface.

public class CurrenySelectionFactory : ISelectionFactory
{
public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
return new ISelectItem[] {
new SelectItem()
{
Text = "Sterling",
Value = "GBP" },
new SelectItem()
{
Text = "Dollars",
Value = "USD" }
};
}
}

On your page or block type, you then decorate your property with a SelectOne/SelectMany and add your CurrentSelectionFactory and job done!

[ContentType]
public class ContentPage : PageData
{
[SelectOne(SelectionFactoryType=typeof(LanguageSelectionFactory))]
public virtual string SingleLanguage { get; set; }
}

And the selection factory code:

When you implement ISelectionFactory you’ll need to implement:

public IEnumerable GetSelections(ExtendedMetadata metadata)

It’s this section of code where you can add your code to fetch whatever data you need.

A Page Type Selection Factory

Now we’ve gone over the basic example that hard codes return values, let’s go over the code you’ll probably be using the majority of time when you are working with selection factories…  code that actually returns dynamic data.

In the example below, we want to return a list of category page types that live under a category root page.  In this project, we have the root page defined in the homepage.  In the get root page method, we search the homepage to find the reference.  When you’re building your site, I would not always recommend using this pattern to store your settings.  In this example it makes the code a bit easier to understand but I would recommend reading The Best Ways To Store Site Settings in Episerver for more insight how to architecture your settings in your project.

public class CategoriesFactory : ISelectionFactory
{
public virtual IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
return GetCategories().Select(d => (new SelectItem() { Text = d.Name, Value = d.Id })).ToList();
}
protected static List<CategoryPageType> GetCategories()
{
var list = new List<CategoryPageType>();
var categoryRootPage = GetCategoriesRootPage();
if (categoryRootPage != null)
{
var categories = categoryRootPage.GetChildren<CategoryPageType>();
if (categories != null && categories.Any())
{
foreach (var category in categories)
{
list.Add(new Category()
{
Name = category.CategoryName,
Id = category.ContentLink.ID.ToString()
});
}
}
}
return list;
}
private static CategoryRootPageType GetCategoriesRootPage()
{
var homepage = ContentReference.StartPage.Get<HomePage>();
return homepage.CategoriesContainer != null
? homepage.CategoriesContainer.Get<CategoryRootPageType>()
: ContentReference.RootPage.GetChild<CategoryRootPageType>().FirstOrDefault();
}
}
}
public class Category
{
public string Id { get; set; }
public string Name { get; set; }
}

In the GetSelections() method we call GetCategories().  In here, we first get a reference to the root page where all our category pages are stored.  I then iterate through the list and add them in a Category object.  In a high traffic project, I would usually use the dynamic data store or cache to save these values for a temporary period, to prevent the constant trips to the database.  After that we return the items as ISelectItem and we’re done.

Conclusion

In today’s tutorial, we’ve managed to populate a drop-down list for a content editor to allow them to attach a category.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *