Module: Page Builder
3 of 15 Pages
Create a dropdown provider
When editors create pages with Page Builder, they utilize components (page templates, sections, widgets), prepared by the developers. Each component has properties, that editors set in the Xperience administration using UI controls, for example, a dropdown selector.
As a developer, you can populate an Xperience dropdown selector with data in two ways:
Pass a “hardcoded” string of options, as you can see in this example.
Create a dropdown provider that maps options dynamically.
This guide covers the second approach. In our example, we use an enumeration to define the dropdown options.
Setting up dropdown mapping is an important building block for the later guides in this Page Builder series, which use dropdown components heavily.
Implement a generic mapper class
The Xperience Dropdown selector has aDataProviderType
property that can take a class, mapping a custom enumeration to specific dropdown options.
While it is viable to implement a custom class per enumeration, a reusable generic class will save you time and lines of code.
First, create a generic DropdownEnumOptionProvider
class that:
- Implements
IDropDownOptionsProvider
- Accepts
struct
andEnum
as the generic type
If you are working in the training guides repository, we recommend placing the class inside ~/Features/Shared/OptionProviders folder in the TrainingGuides.Web project.
Then implement the following methods:
GetOptionItems
- Tells Xperience how to map the enumeration members to dropdown items.
Parse
- Casts a
string
value to the enumeration type. The value from the dropdown selector control comes back asstring
by definition, so the method will come in handy later in your code.
- Casts a
To work with enumerations, our samples use the EnumsNET NuGet package. The library allows you to access the enumeration attributes, like Description, which is handy, for example, to store UI labels for each dropdown option.
Below is the complete code of a generic DropdownEnumOptionProvider
class, for your reference:
using System.ComponentModel;
using EnumsNET;
using Kentico.Xperience.Admin.Base.FormAnnotations;
namespace TrainingGuides.Web.Features.Shared.OptionProviders;
public class DropdownEnumOptionProvider<T> : IDropDownOptionsProvider
where T : struct, Enum
{
public Task<IEnumerable<DropDownOptionItem>> GetOptionItems()
{
// map enum members to DropDownOptionItem
var results = Enums.GetMembers<T>(EnumMemberSelection.All)
.Select(enumItem =>
{
// dropdown item label:
// if available, use Description attribute, otherwise use enum item name
string text = enumItem.Attributes
.OfType<DescriptionAttribute>()
.FirstOrDefault()?.Description
?? enumItem.Name;
// dropdown item value
string value = enumItem.Value.ToString();
return new DropDownOptionItem { Value = value, Text = text };
});
return Task.FromResult(results.AsEnumerable());
}
public virtual T Parse(string value, T defaultValue) =>
Enums.TryParse<T>(value, true, out var parsed)
? parsed
: defaultValue;
}
Use the new mapper class
Let’s demonstrate the enumeration mapping on an existing dropdown selector property of the Landing page template in the main branch of our training guides repository.
If you are working on your own project, feel free to define a property and enumeration values that fit your use case. You will still be able to follow most of the steps below.
Define your enumeration
Examine theLandingPageTemplateProperties.cs
file in TrainingGuides.Web/Features/LandingPages
. The dropdown values are currently defined by a string constant:
...
private const string OPTIONS =
"H1;Heading 1" + "\n" +
"H2;Heading 2" + "\n" +
"H3;Heading 3" + "\n" +
"H4;Heading 4" + "\n" +
"P;Paragraph" + "\n";
[DropDownComponent(
Label = "Message tag type",
Options = OPTIONS,
ExplanationText = DESCRIPTION)]
public string MessageType { get; set; } = "H4";
...
LandingPageHeadingTypeOption
enumeration accordingly.
using System.ComponentModel;
...
public enum LandingPageHeadingTypeOption
{
[Description("Heading 1")]
H1,
[Description("Heading 2")]
H2,
[Description("Heading 3")]
H3,
[Description("Heading 4")]
H4,
[Description("Paragraph")]
P
}
Each enumeration item should match one option in the dropdown component.
The Description of each item is what editors will see as labels in the Xperience administration. If you don’t define a Description attribute, the item’s name becomes the label by default.
Map the enumeration to the dropdown component
Assign the type of DropdownEnumOptionProvider<YOUR_ENUMERATION>
to the DataProviderType
property of the DropDownComponent
.
Next, remove the Options
property, which is no longer needed.
LandingPageHeadingTypeOption
enumeration mapped to the MessageType
dropdown property.
using System.ComponentModel;
using Kentico.PageBuilder.Web.Mvc.PageTemplates;
using Kentico.Xperience.Admin.Base.FormAnnotations;
using TrainingGuides.Web.Features.Shared.OptionProviders;
namespace TrainingGuides.Web.Features.LandingPages;
public class LandingPageTemplateProperties : IPageTemplateProperties
{
private const string DESCRIPTION = "Select the type of Html tag that wraps the home page message";
[DropDownComponent(
Label = "Message tag type",
ExplanationText = DESCRIPTION,
DataProviderType = typeof(DropdownEnumOptionProvider<LandingPageHeadingTypeOption>)
)]
public string MessageType { get; set; } = nameof(LandingPageHeadingTypeOption.H2);
}
// enumeration defining the dropdown values and labels
public enum LandingPageHeadingTypeOption
{
[Description("Heading 1")]
H1,
[Description("Heading 2")]
H2,
[Description("Heading 3")]
H3,
[Description("Heading 4")]
H4,
[Description("Paragraph")]
P
}
If you followed along with the example above, run the TrainingGuides.Web project. When you edit the Home page template in the Xperience administration, the Message tag type property should let you change the style of the “Welcome to Training guides!” message – the same way as before the refactor.