Adding visibility conditions for builder component properties

When defining editable properties for page or form builder components (widgets, page templates, personalization conditions, form field validation rules, etc.) you can use the API to set visibility conditions. Visibility conditions restrict how and when properties are displayed to users in the configuration interface (dialog or panel). Properties can have multiple visibility conditions assigned this way.

Property visibility conditions only work for properties decorated using the EditingComponent attribute. They are NOT applicable to widget properties that users manage through an inline editor.

By default, the system provides a set of conditions that determine visibility based on another property of the same component. For example, you can have a property setting a widget’s heading text, and make it visible only when editors enable another checkbox property to actually display a widget heading. In addition, the system allows you to develop custom visibility conditions suitable for your use cases and scenarios.

Use the following process to add visibility conditions for a component’s properties:

  1. Open your project in Visual Studio.
  2. Edit the class containing the component’s properties (property model, etc.).
  3. Identify the property that you want to hide or display based on a condition.
  4. Decorate the property using the VisibilityCondition attribute (available in the Kentico.Forms.Web.Mvc namespace).
    • You can add multiple visibility condition attributes to a single property. The property is visible if all added visibility conditions are fulfilled.
  5. Specify the following parameters for the VisibilityCondition attribute:
    1. The name of the property on which the condition depends (we recommend using the nameof expression).

    2. To use one of the default condition types, specify a value from the ComparisonTypeEnum enumeration:

      • IsNull, IsNotNull – the related property must be of a reference type.
      • IsEmptyIsNotEmpty – fulfilled if the related property’s value is (or is not) empty or null. The related property’s type must be string or an array/collection implementing IEnumerable<T>.
      • IsTrue, IsFalse – the related property’s type must be bool.
      • IsEqualTo, IsNotEqualTo – fulfilled if the related property’s value is equal (or not equal) to another value specified as an additional parameter of the attribute. For string type values, you can set an additional StringComparison parameter to specify the comparison rules.

The given component’s configuration dialog now displays properties based on your visibility conditions.

Property order requirement

Visibility dependencies between properties are restricted by the order in which the properties are displayed in the configuration dialog. Properties can only depend on properties with a lower order, i.e. those that are shown before them in the dialog.

Examples



using Kentico.Forms.Web.Mvc;

...

// Checkbox property that controls whether the widget displays a heading
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 0, Label = "Show heading")]
public bool ShowHeading { get; set; }

// Textbox property for entering the widget's heading text
// Visible only if the widget's heading is displayed
[EditingComponent(TextInputComponent.IDENTIFIER, Order = 1, Label = "Heading text")]
[VisibilityCondition(nameof(ShowHeading), ComparisonTypeEnum.IsTrue)]
public string HeadingText { get; set; }

// Textbox property for entering a city value
[EditingComponent(TextInputComponent.IDENTIFIER, Order = 2, Label = "City")]
public string City{ get; set; }

// Checkbox property indicating whether the widget offers express shipping
// Visible only if the entered city is "New York"
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 3, Label = "Offer express shipping")]
[VisibilityCondition(nameof(City), ComparisonTypeEnum.IsEqualTo, "New York", StringComparison = StringComparison.OrdinalIgnoreCase)]
public bool ExpressShipping { get; set; }


Developing custom visibility condition types

If the default visibility conditions (provided by the options in the ComparisonTypeEnum enumeration) are not sufficient for your scenarios, the API allows you to develop custom condition types. Custom visibility conditions can evaluate any factors that you include in the code.

There are two types of custom visibility conditions:

  • Conditions that work independently (based on contextual data in the system)
  • Conditions based on another property of the same component

To define a custom visibility condition for builder component properties:

  1. Open your project in Visual Studio.
  2. Create a new class that inherits from one of the following base classes:
    • VisibilityCondition – for independent context-based conditions.

    • AnotherPropertyVisibilityCondition<TValue> – for conditions based on the value of another property. Substitute the TValuegeneric with the typeof the property for which the condition is applicable.

      Both the VisibilityCondition and AnotherPropertyVisibilityCondition base classes are available in the Kentico.Forms.Web.Mvc namespace.

  3. Override the IsVisible method, and add any logic to determine the property’s visibility. The method needs to return either true – the field is displayed, or false– the field remains hidden.
  4. Add any required properties representing configurable parameters for the condition type.
    • Such properties can then be set for individual usages of your custom condition type, using VisibilityConditionProperty attributes.

Your custom condition type can now be assigned to builder component properties through the VisibilityCondition attribute. See Assigning custom conditions to properties.

Examples

Administrator condition



using Kentico.Forms.Web.Mvc;

using CMS.Base;
using CMS.Membership;

namespace LearningKit.FormBuilder.VisibilityConditions
{
    // Visibility condition that evaluates whether the current user
    // in the administration interface has the 'Administrator' privilege level
    public class AdministratorPropertyCondition : VisibilityCondition
    {
        // Determines whether the property is visible
        public override bool IsVisible()
        {
            // True if the current user's privilege level is 'Administrator' or higher
            // In effect, the condition hides properties for users with the 'Editor' level
            return MembershipContext.AuthenticatedUser.CheckPrivilegeLevel(UserPrivilegeLevelEnum.Admin);
        }
    }
}


Condition based on an integer property



using Kentico.Forms.Web.Mvc;

namespace LearningKit.FormBuilder.VisibilityConditions
{
    // Visibility condition that evaluates whether the value of a related integer property is positive, negative or zero
    public class NumberSignPropertyCondition : AnotherPropertyVisibilityCondition<int>
    {        
        // Parameter indicating whether the visibility condition is fulfilled for positive/negative numbers or zero
        public string RequiredSign { get; set; }

        // Determines whether the property is visible
        public override bool IsVisible()
        {
            string requiredSign = RequiredSign.ToLower();

            switch (requiredSign)
            {
                case "zero":
                    return DependeePropertyValue == 0;
                case "positive":
                    return DependeePropertyValue > 0;
                case "negative":
                    return DependeePropertyValue < 0;
                default:
                    return false;
            }
        }
    }
}


Assigning custom conditions to properties

After you develop a custom visibility condition type, you can assign it to builder component properties:

  1. Edit the class containing the component’s properties (property model, etc.).
  2. Identify the property that you want to hide or display based on the condition.
  3. Decorate the property using the VisibilityCondition attribute (available in the Kentico.Forms.Web.Mvc namespace).
  4. Specify the following parameters for the VisibilityCondition attribute:
    1. For conditions that evaluate based on another component property – the name of the property on which the condition depends (we recommend using the nameof expression).
    2. The System.Type of your custom visibility condition class (use the typeof operator).
  5. If the custom visibility condition type has any configurable parameters (properties), set their values using VisibilityConditionProperty attributes with the following arguments:
    1. The name of the visibility condition property.
    2. The value that you want to set for the given occurrence of the condition (must match the property’s type).
  6. If you are assigning multiple visibility conditions with configurable parameters (properties), you must provide the optional ConditionName argument to the constructors of the VisibilityCondition and VisibilityConditionProperty attributes. The system uses ConditionName to pair condition parameters to the corresponding visibility conditions.

The custom visibility condition now applies to the given property in the component’s configuration dialog.

Examples - single visibility condition per property



using Kentico.Forms.Web.Mvc;

...

[EditingComponent(IntInputComponent.IDENTIFIER, Order = 0, Label = "Number")]
public int Number { get; set; }

// Property visible only for users with the 'Administrator' privilege level
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 1, Label = "Admin property")]
[VisibilityCondition(typeof(AdministratorPropertyCondition))]
public bool AdminProperty { get; set; }

// Property visible only if the 'Number' property's value is positive
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 2, Label = "Positive property")]
[VisibilityCondition(nameof(Number), typeof(NumberSignPropertyCondition))]
[VisibilityConditionProperty(nameof(NumberSignPropertyCondition.RequiredSign), "positive")]
public bool PositiveProperty { get; set; }

// Property visible only if the 'Number' property's value is negative
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 3, Label = "Negative property")]
[VisibilityCondition(nameof(Number), typeof(NumberSignPropertyCondition))]
[VisibilityConditionProperty(nameof(NumberSignPropertyCondition.RequiredSign), "negative")]
public bool NegativeProperty { get; set; }


Example - multiple visibility conditions per property



[EditingComponent(IntInputComponent.IDENTIFIER, Order = 0, Label = "Number")]
public int Number { get; set; }

// Property visible only if the 'Number' property's value is negative
[EditingComponent(CheckBoxComponent.IDENTIFIER, Order = 3, Label = "Negative property")]
// Pairs 'NumberSignPropertyCondition' and its parameters
[VisibilityCondition(nameof(Number), typeof(NumberSignPropertyCondition), nameof(NumberSignPropertyCondition))]
[VisibilityConditionProperty(nameof(NumberSignPropertyCondition.RequiredSign), "negative", nameof(NumberSignPropertyCondition))]
// Pairs 'ParameterizedVisibilityCondition' and its parameters
[VisibilityCondition(nameof(Number), typeof(ParameterizedVisibilityCondition), nameof(ParameterizedVisibilityCondition))]
[VisibilityConditionProperty(nameof(ParameterizedVisibilityCondition.Parameter1), "value", nameof(ParameterizedVisibilityCondition))]
public bool NegativeProperty { get; set; }