Skip to main content

Hiding / Showing Widgets

Your backend can control the visibility of any widget at runtime by returning a widgetsState object in the response. Use this to show or hide sections, fields, and buttons based on data, roles, or workflow state.

When your handler calls SetWidgetsState(), the visibility and read-only state are included in the /runevent response. The SDK applies them to the form immediately.


Response structure

widgetsState contains two dictionaries:

{
"widgetsState": {
"visibility": {
"phoneSection": false,
"adminPanel": false
},
"readOnly": {
"createdDate": true,
"customerId": true
}
}
}
  • visibilitytrue shows the widget, false hides it. Omitting a widget from the dictionary leaves its current visibility unchanged.
  • readOnlytrue makes the widget non-editable, false makes it editable.

C# implementation

public async Task Form_onInit(bool isInitialLoad)
{
var visibility = new Dictionary<string, bool>();
var readOnly = new Dictionary<string, bool>();

// Hide internal fields for non-admin users
if (!Context.CurrentUser.IsAdmin())
{
visibility["internalNotes"] = false;
visibility["costPrice"] = false;
}

// Make audit fields read-only for everyone
readOnly["createdAt"] = true;
readOnly["createdBy"] = true;

SetWidgetsState(visibility, readOnly);
}

Dynamic visibility on field change

public async Task paymentType_onChange(string? value)
{
bool isBankTransfer = value == "bank";
bool isCreditCard = value == "card";

SetWidgetsState(
visibility: new Dictionary<string, bool>
{
{ "bankDetailsSection", isBankTransfer },
{ "cardDetailsSection", isCreditCard },
{ "chequeNumberField", value == "cheque" }
},
readOnly: new Dictionary<string, bool>()
);
}

Showing a widget after validation passes

public async Task Form_onClick(string widgetName)
{
if (widgetName == "validatebtn")
{
bool isValid = await ValidateForm(record.GetData());

SetWidgetsState(
visibility: new Dictionary<string, bool>
{
{ "submitSection", isValid },
{ "validationError", !isValid }
},
readOnly: new Dictionary<string, bool>()
);

if (!isValid)
ShowMessage("warning", "Please correct the errors below.");
}
}

Widget names

Widget names are the Name property set in the Form Builder, always in lowercase. You can target individual widgets or container widgets (Rows, Tab Boxes) to show/hide entire sections at once.

Hide a Row to hide multiple fields

If you place several fields inside a Row widget, you can hide the entire row (and all contained fields) by targeting the Row widget's name — instead of hiding each field individually.