UI form component visibility conditions
Form component visibility conditions control the visibility of inputs within the configuration dialogs of admin UI, Page Builder, and Form Builder components.
Visibility conditions are assigned directly to configuration properties of supported components via C# attribute notation (each property represents a field in the corresponding configuration dialog).
A visibility condition consists of logic that evaluates whether a given field is displayed – implemented in the condition’s Evaluate
method – and, optionally, a set of configuration properties.
Define visibility conditions
Unless specified otherwise, all classes and members mentioned in this section can be found in the
Kentico.Xperience.Admin.Base.Forms
Kentico.Xperience.Admin.Base.FormAnnotations
namespaces.
Visibility conditions are defined and evaluated on the application’s back end (the ASP.NET Core project). Their architecture is summarized by the following diagram:
The visibility of an input is determined using:
- contextual information from the system (e.g., about the current user)
- other inputs in the form
- completely custom logic
With this in mind, visibility conditions can be classified into two categories:
- Conditions without field dependencies – determine the visibility of an input based solely on external or contextual information and custom logic.
- Conditions with field dependencies – use other fields in the form to determine the visibility of an input.
Visibility conditions without field dependencies
This type of visibility condition determines field visibility using information external to the form itself (e.g., information about the current user).
Visibility conditions must inherit from the VisibilityCondition<TProperties>
base class, where
TProperties
– holds properties required for the functionality of the condition. The class must inherit from theVisibilityConditionProperties
base class.C#Visibility condition properties classpublic class MyVisibilityConditionProperties : VisibilityConditionProperties { // Properties required for the functionality of the condition... }
and implement the Evaluate
method. The method must return either true
– indicating that the field is visible, or false
– indicating that the field is hidden. The condition’s configuration properties can be accessed via VisibilityCondition<TProperties>.Properties
.
public class MyVisibilityCondition : VisibilityCondition<MyVisibilityConditionProperties>
{
public override bool Evaluate(IFormFieldValueProvider formFieldValueProvider)
{
// Visibility evaluation...
// Properties can be accessed via 'Properties'
Properties.ConfigurationProperty1...
}
}
Dependency injection support
Visibility conditions support constructor dependency injection. You can use dependency injection to resolve instances of services on which the visibility condition depends.
To make the condition assignable to properties, create a corresponding attribute class – see Assign visibility conditions.
Visibility conditions with field dependencies
This type of condition uses inputs from other fields in the form to determine a field’s visibility.
To implement this type of visibility condition:
- Create a regular visibility condition
- Add support for field dependencies
- Access their values when evaluating visibility
- Make the condition assignable to properties
Add support for field dependencies
Conditions with dependencies need to locally store the names of the fields (other configuration properties within the component configuration dialog) on which they depend. The system uses this information to mark fields on which at least one visibility condition depends. A change in a marked field’s input triggers a re-evaluation of all related visibility conditions.
For this purpose, the VisibilityCondition<TProperties>
base class contains the virtual DependsOnFields
property, which holds the collection of field names as IEnumerable<string>
. This property needs to be overriden in the class implementing the visibility condition and assigned a collection of field names on which the visibility evaluation depends. The field names must be provided via configuration properties when assigning the visibility condition.
Xperience API provides native support for conditions that depend on one other field via the following classes:
VisibilityConditionWithDependencyProperties
– visibility condition properties class with one predefined property –PropertyName
. The property holds the name of the field on which the visibility evaluation depends.C#Example - AnotherPropertyValueVisibilityConditionProperties usagepublic class MyVisibilityConditionProperties : VisibilityConditionWithDependencyProperties { // Additional configuration properties for 'MyVisibilityCondition' } // The implementation of the 'VisibilityConditionWithDependencyProperties' class from the Xperience API public class VisibilityConditionWithDependencyProperties : VisibilityConditionProperties { public string PropertyName { get; set; } }
VisibilityConditionWithDependency<TProperties>
– extends theVisibilityCondition<TProperties>
class with support for conditions that depend on a single other field. Intended to be used together withVisibilityConditionWithDependencyProperties
. EnsuresDependsOnFields
is populated with the name of the dependency provided viaVisibilityConditionWithDependencyPropertie.PropertyName
.C#Example - AnotherPropertyValueVisibilityCondition usagepublic class MyVisibilityCondition : VisibilityConditionWithDependency<MyVisibilityConditionProperties> { } // The implementation of the 'VisibilityConditionWithDependency<TProperties>' class from the Xperience API public abstract class VisibilityConditionWithDependency<TProperties> : VisibilityCondition<TProperties> where TProperties : VisibilityConditionWithDependencyProperties, new() { // Assigns the name of the property on which the condition depends to the collection public override IEnumerable<string> DependsOnFields => Enumerable.Repeat(Properties.PropertyName, 1); }
This approach can be extended to write conditions that depend on N other inputs.
Access field values
Visibility conditions can only depend on fields that precede the currently evaluated field in the given form. For example, if a form comprises inputs A, B, C a visibility condition assigned to C can only depend on fields A and B. Note that the field order in the resulting form can be influenced by the Order
property specified when assigning editing components.
To work with the values of fields on which the condition depends, the Evaluate
method provides an instance of IFormFieldValueProvider
. The provider enables access to the values of all preceding form field inputs. For example, if a form comprises inputs A, B, C and visibility is currently being evaluated on C, IFormFieldValueProvider
can be used to access the values of A and B.
To get field values, use:
TryGet<TType>(string fieldName, out var fieldValue)
– returns the value of the given field asTType
where fieldName
is the name of the dependency from which to retrieve the value (provided via a configuration property – e.g., VisibilityConditionWithDependencyProperties.PropertyName
).
public class MyVisibilityCondition : VisibilityConditionWithDependency<MyVisibilityConditionProperties>
{
public override bool Evaluate(IFormFieldValueProvider formFieldValueProvider)
{
// Gets the value of the field as object
formFieldValueProvider.TryGet<string>(Properties.PropertyName, out var fieldValue);
// Use the value in visibility evaluation...
}
}
public class MyVisibilityConditionProperties : VisibilityConditionWithDependencyProperties
{
// Additional configuration properties for 'MyVisibilityCondition'
}
Assign visibility conditions
Visibility conditions are supported in dynamically created configuration dialogs of Page Builder and Form Builder components and other admin UI components:
- Page Builder
- widget configuration and personalization
- section configuration
- page template configuration
- Form Builder
- form component configuration
- form section configuration
- Admin UI
- form component configuration
- validation rule configuration
- visibility condition configuration
Visibility conditions are assigned using attribute notation to the properties of model classes defining the configuration dialogs of supported components. For example:
using Kentico.PageBuilder.Web.Mvc;
using Kentico.Xperience.Admin.Base.FormAnnotations;
public class BannerWidgetProperties : IWidgetProperties
{
...
[CheckboxInputComponent(Label = "Show link", Order = 1)]
public bool ShowLink { get; set; }
[TextInputComponent(Label = "Link URL", Order = 2, WatermarkText = "Enter a URL...")]
// The 'VisibleIfTrue' condition only shows link-related properties in the dialog if 'ShowLink' is selected
[VisibleIfTrue(nameof(ShowLink))]
public string LinkUrl { get; set; }
[TextInputComponent(Label = "Link title", Order = 3)]
// The 'VisibleIfTrue' condition only shows link-related properties in the dialog if 'ShowLink' is selected
[VisibleIfTrue(nameof(ShowLink))]
// The 'VisibleIfNotEmpty' condition hides 'LinkTitle' from the properties dialog until 'LinkUrl' is provided
[VisibleIfNotEmpty(nameof(LinkUrl))]
public string LinkTitle { get; set; } = String.Empty;
}
Multiple visibility conditions
A single property can have multiple visibility conditions assigned. The property is visible if all added visibility conditions are fulfilled.
However, be mindful not to create contradictory rulesets that could make the field permanently hidden.
Each visibility condition must have a corresponding attribute. When the attribute is used to annotate a property of one of the supported components, the condition applies to that property’s input.
Visibility condition attribute classes must inherit from VisibilityConditionAttribute
or derived classes:
VisibilityConditionAttribute
– for rules that depend only on data that can be obtained contextually (e.g., a user’s assigned role).VisibilityConditionWithDependencyAttribute
– for rules that depend on a single other field in the configuration dialog (e.g., the example snippet above). The class extends the baseVisibilityConditionAttribute
class with a property that holds the name of the field on which the condition depends. This pattern can be adapted for conditions with dependencies on an arbitrary number of inputs.
Declare all mandatory and optional properties of the corresponding validation rule as properties of the attribute class. The properties:
- must be named identically to the properties in the visibility condition class. The system uses the property names to instantiate the corresponding condition.
- must be of the same type as the corresponding property in the visibility condition.
Properties that are required for the condition to function can be forced via the attribute’s constructor.
public class ValueIsBetweenVisibilityConditionAttribute : VisibilityConditionWithDependencyAttribute
{
public int Maximum { get; set; }
public int Minimum { get; set; }
// Use the attribute constructor to force properties required for the correct
// functionality of the visibility condition
public ValueIsBetweenVisibilityConditionAttribute(string propertyName,
int max, int min) : base(propertyName)
{
Maximum = max;
Minimum = min;
}
}
To indicate the relation between the attribute class and the corresponding validation rule, decorate the validation rule class with the VisibilityConditionAttribute
attribute.
[VisibilityConditionAttribute(typeof(ValueIsBetweenVisibilityConditionAttribute))]
public class ValueIsBetweenVisibilityCondition : VisibilityConditionWithDependency<TProperties>
For the example above, every property decorated with ValueIsBetweenVisibilityConditionAttribute
is assigned the ValueIsBetweenVisibilityCondition
condition.
Default visibility conditions
The following table provides an overview of visibility conditions provided with a default Xperience installation. All visibility condition attributes are located in the Kentico.Xperience.Admin.Base.FormAnnotations
namespace.
Visibility condition | Attribute | Description |
Visible if B empty | VisibleIfEmptyAttribute | The decorated property A is visible if property B is empty (an empty string, an empty collection, or |
Visible if B not empty | VisibleIfNotEmptyAttribute | The decorated property A is visible if property B is not empty. |
Visible if B equal to | VisibleIfEqualToAttribute | The decorated property A is visible if property B is equal to the specified string or object. |
Visible if B not equal to | VisibleIfNotEqualToAttribute | The decorated property A is visible if property B is not equal to the specified string or object. |
Visible if B true | VisibleIfTrueAttribute | The decorated property A is visible if property B is (boolean) |
Visible if B false | VisibleIfFalseAttribute | The decorated property A is visible if property B is (boolean) |
Example
The following example shows how to implement a visibility condition that checks if the value entered into another input in the form falls into the specified integer interval. Based on the result, the condition displays or hides its assigned field accordingly.
From the task definition, we know that we need to create a visibility condition that depends on one other input in the form. To achieve this, we can use VisibilityConditionWithDependency<TProperties>
and VisibilityConditionWithDependencyProperties
provided by the Xperience API. The classes ensure our visibility condition gets correctly configured, leaving us to focus on the implementation of the Evaluate
method and requried configuration properties.
The condition’s properties class needs to store two values – the lower and upper boundary of the accepted interval. Should the input fall outside this interval, the field to which this condition is assigned is hidden.
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.Base.FormAnnotations;
public class ValueIsBetweenVisibilityConditionProperties : VisibilityConditionWithDependencyProperties
{
public int Maximum { get; set; }
public int Minimum { get; set; }
}
Within the condition’s main class, we implement the Evaluate
method, access the value of the field on which the condition depends (using the field name provided when configuring the condition) via IFormFieldValueProvider
and use it to evaluate the condition.
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.Base.FormAnnotations;
public class ValueIsBetweenVisibilityCondition : VisibilityConditionWithDependency<ValueIsBetweenVisibilityConditionProperties>
{
public override bool Evaluate(IFormFieldValueProvider formFieldValueProvider)
{
// Gets the value of the field on which the condition depends
formFieldValueProvider.TryGet<int>(Properties.PropertyName, out var dependeeField);
return (dependeeField >= Properties.Minimum) && (dependeeField <= Properties.Maximum);
}
}
Now we need to create the corresponding attribute to enable usage in component model classes.
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.Base.FormAnnotations;
public class ValueIsBetweenVisibilityConditionAttribute : VisibilityConditionWithDependencyAttribute
{
public int Maximum { get; set; }
public int Minimum { get; set; }
// The 'VisibilityConditionWithDependencyAttribute' base class enforces the field dependency via the constructor
public ValueIsBetweenVisibilityConditionAttribute(string propertyName,
int max, int min) : base(propertyName)
{
Maximum = max;
Minimum = min;
}
}
With the attribute created, add VisibilityConditionAttribute
with the attribute type as the parameter to the condition’s main class to tie the attribute and visibility condition together.
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.Base.FormAnnotations;
[VisibilityConditionAttribute(typeof(ValueIsBetweenVisibilityConditionAttribute))]
public class ValueIsBetweenVisibilityCondition : VisibilityConditionWithDependency<ValueIsBetweenVisibilityConditionProperties>
The visibility condition is now ready to be used.