Rendering Customizations

This guide explains how to use the tag property on a field within the data model to customize its behavior in the UI when using @socotra/ec-react-components.

Hiding Fields

For fields that should be part of the data model but should almost never be shown in the UI, you can use the simple hidden tag. This tag removes the field from the form schema during generation, ensuring it does not render.

This provides a way to control field visibility at the data-model level, rather than passing a prop to every form instance. The only way to make a hidden field appear is to pass its name in the hiddenExceptions array prop on the form component, making it a deliberate choice to show it.

  • Tag Format: hidden

Example

Imagine you have an internalNotes field on your Quote data model. This field should be saved with the quote data but should not be visible on the standard quote form.

Data Model Configuration:

{
  "internalNotes": {
    "type": "string",
    "displayName": "Internal Notes",
    "tag": ["hidden"]
  },
  "premiumAmount": {
    "type": "decimal",
    "displayName": "Premium Amount",
    "tag": ["currency.USD"]
  }
}

Result:

  • By default, the QuoteForm will not display the “Internal Notes” field. It is completely removed from the generated schema.

  • If you have a special administrative view where you do want to show this field, you would render the QuoteForm with the hiddenExceptions prop:

    <QuoteForm
      // ... other props
      hiddenExceptions={['internalNotes']}
    />
    

    Only in this specific instance would the “Internal Notes” field appear.

Hiding Fields Conditionally

The forms support two distinct methods for hiding fields based on the values of other fields:

  1. Dynamic Client-Side Hiding: Hides a field based on the value of another field within the same form. This is ideal for dynamic UIs where you want a field to appear or disappear immediately as the user makes selections.

  2. Static Schema-Level Hiding: Hides a field based on a value from the root quote object. This is useful when a field’s visibility depends on a more global state that doesn’t change within the context of the current form.

Dynamic Client-Side Hiding (hidden|...)

This method uses a UI schema rule to show or hide a field. The change happens instantly on the client-side without a backend call.

  • Tag Format: hidden|{fieldName}{operator}{value}

    • fieldName: The name of the field within the same data model level whose value will be checked.

    • operator: Must be either == (equals) or != (not equals).

    • value: The value to check against (e.g., true, CAR, 123).

Example

Imagine you have a vehicleType field and you only want to show the vin field if the vehicleType is “CAR”.

Data Model Configuration:

On your vin field, you would add the following tag:

{
  "vin": {
    "type": "string",
    "displayName": "VIN",
    "tag": ["hidden|vehicleType!=CAR"]
  },
  "vehicleType": {
    "type": "string",
    "displayName": "Vehicle Type",
    "options": ["CAR", "MOTORCYCLE", "BOAT"]
  }
}

Result:

  • The “VIN” field will be hidden by default.

  • If the user selects “CAR” from the “Vehicle Type” dropdown, the “VIN” field will instantly appear.

  • If the user selects “MOTORCYCLE” or “BOAT”, the “VIN” field will remain hidden.

Static Schema-Level Hiding (rootHidden|...)

This method filters a field out of the JSON Schema itself during its creation. This is best when the condition for hiding is based on data outside the immediate form’s scope, specifically from the root quote’s element data.

  • Tag Format: rootHidden|{fieldName}{operator}{value}

    • fieldName: The name of a field located at the quote.element.data path.

    • operator: Must be either == or !=.

    • value: The value to check against.

Example

Suppose you have an additionalInsured element on your quote. You want to hide the relationshipToPrimary field within that element if the policyHolderType (a field on the root quote’s element) is “INDIVIDUAL”.

Data Model Configuration:

On your relationshipToPrimary field (inside the additionalInsured element’s model), you would add the following tag:

{
  "relationshipToPrimary": {
    "type": "string",
    "displayName": "Relationship to Primary Insured",
    "tag": ["rootHidden|policyHolderType==INDIVIDUAL"]
  }
}

Result:

  • When the ElementForm for the additionalInsured element is rendered, the system checks the value of quote.element.data.policyHolderType.

  • If the value is “INDIVIDUAL”, the relationshipToPrimary field will be completely omitted from the form’s schema and will not be rendered.

  • If the value is anything else (e.g., “CORPORATION”), the field will be included in the schema and rendered in the form.

Horizontal Layout for Custom Data Types

When working with custom data types (repeatable sets of fields like a “Driver” or “Vehicle”), you can control how the fields are displayed. By default, fields are rendered in a two-column layout. By using the horizontal-layout tag, you can force the fields within that custom data type to render in a single-column layout, where each field takes up the full width of its row.

  • Tag Format: horizontal-layout

Example

Imagine you have a Driver custom data type that contains driverName and licenseNumber fields. You want to add a list of drivers to a quote, but you want each driver’s fields to be laid out horizontally for better readability.

Data Model Configuration:

  1. Define your Driver custom data type.

  2. On the field in your product model that references the Driver type, add the horizontal-layout tag.

// In your product's data model
{
  "drivers": {
    "type": "Driver*", // This is an array of the "Driver" custom data type
    "displayName": "Drivers",
    "tag": ["horizontal-layout"] // Apply the tag here
  }
}

// In your dataTypes configuration
{
  "Driver": {
    "displayName": "Driver",
    "data": {
      "driverName": {
        "type": "string",
        "displayName": "Driver Name"
      },
      "licenseNumber": {
        "type": "string",
        "displayName": "License Number"
      }
    }
  }
}

Result:

When the form renders the “Drivers” section, instead of stacking the “Driver Name” and “License Number” fields in a two-column grid, each driver entry will be displayed in its own row, with the “Driver Name” label and input field appearing next to each other, taking up the full available width. This provides a more compact and linear layout for nested data.

Multi-Select Dropdown for Arrays

For fields that are an array of primitive values (like string* or int+) and have a predefined list of choices, you can use the multiselect tag to render the input as a multi-select dropdown or checkbox group instead of the default array input UI.

  • Tag Format: multiselect

  • Prerequisites:

    • The field type must be an array of primitives (e.g., string*, string+, int*).

    • The field definition must include an options array containing the list of choices.

Example

Imagine you want users to select multiple “coverage add-ons” from a list for their policy.

Data Model Configuration:

On your coverageAddOns field, you define it as an array of strings, provide the list of options, and add the tag.

{
  "coverageAddOns": {
    "type": "string*",
    "displayName": "Coverage Add-ons",
    "tag": ["multiselect"],
    "options": [
      "Roadside Assistance",
      "Rental Reimbursement",
      "Towing and Labor",
      "Glass Coverage"
    ]
  }
}

Result:

  • Without the tag: The UI would render a label “Coverage Add-ons” with an “Add” button. Clicking “Add” would create a new select input field, forcing the user to select 1 option at a time.

  • With the ``multiselect`` tag: The UI renders a single multi-select dropdown or a group of checkboxes with all the options listed, allowing the user to easily select multiple items from the predefined list.

Rendering as a Radio Group

For fields that have a small, fixed set of options, you can use the radio-group tag to display them as a set of radio buttons instead of a dropdown. This is often more user-friendly when there are only a few choices.

  • Tag Format: radio-group

  • Prerequisites:

    • The field type must be string.

    • The field definition must include an options array with the available choices.

Example

Suppose you have a region field where the user must select either “West” or “East”.

Data Model Configuration:

On your region field, you define it as a string, provide the list of options, and add the tag.

{
  "region": {
    "type": "string",
    "displayName": "Region",
    "options": ["West", "East"],
    "tag": ["radio-group"]
  }
}

Result:

  • Without the tag: The UI would render a standard dropdown menu with “West” and “East” as options.

  • With the ``radio-group`` tag: The UI will render two radio buttons, one for “West” and one for “East”, allowing the user to see all options at a glance and select one.

Displaying Currency Fields

To ensure that number fields are correctly formatted and displayed as currency in the UI, you need to add a specific currency tag. This tag tells the renderer to apply currency formatting, such as adding a currency symbol (e.g., “$”) and appropriate delimiters.

  • Tag Format: currency.{CURRENCY_CODE}

    • CURRENCY_CODE: The standard three-letter ISO 4217 currency code (e.g., USD, EUR, JPY).

Example

You have a field for premiumAmount that should be treated as US Dollars.

Data Model Configuration:

On your premiumAmount field, you add the currency.USD tag.

{
  "premiumAmount": {
    "type": "decimal",
    "displayName": "Premium Amount",
    "tag": ["currency.USD"]
  }
}

Result:

The UI will render the “Premium Amount” field as a currency input. As the user types, it will automatically be formatted with a dollar sign, commas for thousands separators, and will handle decimal places appropriately, for example, displaying $1,234.50.