In the first part of the series we learned how to build the frame of a Peakboard extension. We used two classes to provide both metadata and the actual payload that is exchanged between the extension and the Peakboard application. Here’s an overview of this article series:
- Part I - The Basics
- Part II - Parameters and User Input
- Part III - Custom-made Functions
- Part IV - Event-triggered data sources
In today’s article we will talk about how to build a user interface to let the user configure the extension. Typical parameters would be a URL or credentials to the source system. The understanding of the frame we discussed in the first part of the series is a crucial requirement. The sample code used in this article can be found at github.
Add a simple parameter
To add a parameter we will need to adjust the GetDefinitionOverride override and just add it to the PropertyInputDefaults collection and also set the PropertyInputPossible to true. In this example we will add a very simple text parameter named CatsName to our list.
protected override CustomListDefinition GetDefinitionOverride()
{
return new CustomListDefinition
{
ID = "CatCustomList",
Name = "Cat List",
Description = "A custom list for cats with breed and age information",
PropertyInputPossible = true,
PropertyInputDefaults =
{
new CustomListPropertyDefinition { Name = "CatsName", Value = ""}
}
};
}The screenshot shows how the parameter looks in the Peakboard Designer UI.

To access the value of the user input we use the data object that is provided in the GetItemsOverride function. We can easily access all parameters through the Properties collection. The source code also shows how to generate a log entry. It uses the Log object to generate messages. All types of messages, for example Info, Verbose, Error, Critical, etc…. are supported in the same way.
protected override CustomListObjectElementCollection GetItemsOverride(CustomListData data)
{
this.Log.Info("Generating cat list items for " + data.Properties["CatsName"]);
// ....
}The extension kit offers a standardized way to check the user input and prevent the data source dialog from being closed when the validation of the values fails. This happens in the overridable function CheckDataOverride. In case there’s anything wrong with the value we can throw an exception that is routed to the user and prevents the dialog from being closed.
protected override void CheckDataOverride(CustomListData data)
{
if (string.IsNullOrWhiteSpace(data.Properties["CatsName"]))
{
throw new InvalidDataException("Please provide a good name");
}
base.CheckDataOverride(data);
}Complex parameters
Besides the simple text parameter we have the option to force the value of a parameter into the other Peakboard data types such as number or bool. All the additional parameter objects are added to the PropertyInputDefaults collection.
new CustomListPropertyDefinition { Name = "IsItARealCat", Value = "True", TypeDefinition = TypeDefinition.Boolean },
new CustomListPropertyDefinition { Name = "Age", Value = "4", TypeDefinition = TypeDefinition.Number },The dialogs to manipulate the data are adjusted automatically according to this meta data.

Let’s assume we want to give the user only a combo box of distinct values to be chosen rather than a free text, we just use the selectableValues attribute to restrict the entry to some values.
new CustomListPropertyDefinition { Name = "MaximumOfSomething", Value = "5",
TypeDefinition = TypeDefinition.Number.With(selectableValues: [ 2, 3, 5, 10, 20, 50, 100]) },Here’s the corresponding view for the user of the extension to provide the distinct values they can choose from:

For passwords, connection strings or other potentially sensitive data, we can use the TypeDefinition attribute masked: true
new CustomListPropertyDefinition { Name = "MySecretCode", Value = "18899", TypeDefinition = TypeDefinition.String.With(masked: true) },Here’s a sample screenshot of a masked parameter:

The last thing we want to discuss are multliline texts. These are typically used for long SQL statement or JSON / XML fragments.
new CustomListPropertyDefinition { Name = "MultilineDescription",
Value = "Please provide\nsome\nbeautiful SQL", TypeDefinition = TypeDefinition.String.With(multiLine: true) }And here’s how it looks like as part of the data source dialog UI.

result
Defining the parameters of an extension with a good UI is a key point to make it as easy as possible for the user to provide his data. We need to choose them wisely :-)
In the next part of our series we learn how to build functions that can be used in both LUA scripts and building blocks: Part III - Custom-made Functions