Skip to main content

JSON Schema Reference

The tSM Form Designer uses JSON Schema as a foundation to define the data model and validation rules of a form. However, it also introduces additional layout, widget, and config fields that govern UI structure, conditional rendering, styling, and interactivity.

This document focuses on those tSM-specific extensions—how the schema is structured, and how to use the extra properties. For standard JSON Schema rules (types, properties, required, etc.), refer to the official JSON Schema documentation.


1. Overview of JSON Schema + tSM Extensions

A tSM-based form definition typically contains:

  1. JSON Schema fields (standard):

    • type: could be "layout","object", "array", "string", "number" or "boolean"
    • properties: an object defining the form’s fields (e.g., "firstName", "age", etc.). Each field in properties can have:
      • A title
      • A description
      • A type
      • Standard validation (e.g., "minLength", "maxLength")
      • A "default" value
      • required: an array on the root schema that lists mandatory properties.
    • oneOf, anyOf, allOf, etc. (optional advanced schema constructs).
  2. tSM Extensions (added on top of JSON Schema):

    • layout: Describes how fields (or nested layouts) are arranged in the UI. Instead of showing all properties in a default top-to-bottom manner, you define columns, tabs, cards, etc.
    • widget: Declares which UI component (e.g., text field, date picker, custom control) should be used to render a field or layout container, plus potential styling or custom attributes.
    • config: Key-value pairs for specialized configuration. This can include styles, condition expressions, references to scripts, or anything else the tSM rendering engine supports.

The form engine merges standard JSON Schema validation with tSM’s layout-based approach to produce a dynamic user interface.


2. Minimal Example

Below is a simplified form demonstrating these concepts:

{
"type": "object",
"properties": {
"firstName": {
"type": "string",
"title": "First Name",
"widget": {
"type": "text"
}
},
"lastName": {
"type": "string",
"title": "Last Name",
"widget": {
"type": "text"
}
}
},
"required": ["firstName"],
"layout": [
{
"type": "layout",
"items": [
"firstName",
"lastName"
],
"widget": {
"type": "dtl-fluent-section"
},
"config": {
"legend": "Enter your name"
}
}
]
}

Explanation:

  1. type: "object"
    Standard JSON Schema: we have an object with named properties.

  2. properties:

    • firstName: standard JSON Schema type ("string"), with a tSM widget extension ("type": "text"), meaning a text input in the UI.
    • lastName: similarly a simple text field.
  3. required: ["firstName"]
    Standard JSON Schema array indicating firstName must not be empty.

  4. layout: []
    An array of layout entries:

    • type: "layout"` This signals a container that can hold multiple items.
    • items: ["firstName", "lastName"]
      Here, we directly reference the property keys to place them in this layout block, in the given order.
    • widget: {"type": "dtl-fluent-section"}
      tSM extension that says: use a “section” container for these items.
    • config: {"legend": "Enter your name"}
      Arbitrary key-value pairs for additional form-engine logic—here, maybe a legend or heading for the section.

This simple example shows how layout organizes the fields, widget declares which UI component or container to render, and config provides additional parameters (like legend text).

For more advanced usage—multi-column layouts, tabs, nested sections, conditionals, etc.—the pattern is similar but the layout and config structures become more complex.


3. Detailed Explanation of tSM Extensions

3.1 Layout

layout is an array of objects that represent the structure of the form. Each object in layout can be:

  • A reference to a property key (string "firstName", etc.)
    This is a shortcut to place a single field where it should appear in the form.

  • A "layout" type (a nested container with multiple items)
    Describes columns, tabs, cards, or other grouping constructs.

Common Fields Inside Each Layout Item

  1. type: "layout"
    Indicates a container that can hold either other layout objects or direct references to schema properties.

  2. items: []
    An array of children. Each element can be:

    • A string referencing a property name (to place a specific field).
    • Another layout object (to nest further sections/tabs/columns).
  3. widget: { ... }
    Describes the type of container widget to use (e.g., "dtl-fluent-section", "dtl-fluent-columns", "dtl-fluent-tab"). The type here is the unique identifier of the widget (for example, "type": "dtl-fluent-section").
    In addition, the widget object holds common properties for that particular widget type, such as placeholders, labels, or basic validation messages.
    The exact set of widget types depends on your tSM environment.

  4. config: { ... }
    A place for advanced or specialized properties used by the widget. These properties vary depending on the widget type. For example:

  • Columns layout: config.columns
  • Tabs layout: config.tabs
  • Legend, Title, Bordered, etc.
  1. hidden, readonly, or other boolean expressions
    (Optional) Condition expressions, typically a string with an expression engine (e.g., "${$value.myField == 'something'}"). This toggles visibility or other states at runtime.

Example of a Multi-Column Layout

{
"type": "layout",
"widget": { "type": "dtl-fluent-columns" },
"config": {
"columns": [
{
"width": 6,
"content": ["firstName"]
},
{
"width": 6,
"content": ["lastName"]
}
]
}
}

This describes a 2-column layout—each column having a 50% width—and places firstName in the left column, lastName in the right column.


3.2 Widget

Every property or layout container can include a widget object to define how it appears in the UI.

  • For properties (form fields), widget.type might be "text", "textarea", "checkbox", "select", "tsm-autocomplete", etc.
  • For layout containers, widget.type might be "dtl-fluent-section", "dtl-fluent-tab", "dtl-fluent-card", etc.

The widget.type is a unique widget identifier, and the rest of the widget object can include common settings (like placeholders or general validation messages) that apply to that specific widget type.

Example:

"firstName": {
"type": "string",
"widget": {
"type": "text",
"placeholder": "Enter first name",
"validationMessages": {
"required": "First name is required!"
}
}
}

Here,

  • "type": "text" means a standard text input field.
  • "placeholder": "Enter first name" sets a hint.
  • "validationMessages" override default error messages.

3.3 Config

config is an open-ended object that can store additional settings for either a field or a layout container. Typically it includes:

  • Styling or spacing data: margins, borders, classes.
  • Script references or dynamic expressions.
  • Metadata for any custom business logic.

These config details tend to be widget-specific. For instance, a "dtl-fluent-card" might have "config.header" for a title or "config.collapsible" to fold the card, while a dropdown widget might have "config.dataSource" pointing to external data.

Example in a layout container:

{
"type": "layout",
"widget": { "type": "dtl-fluent-card" },
"config": {
"header": "User Information",
"cardType": "primary",
"collapsible": true
},
"items": ["firstName", "lastName"]
}

The form engine might render a “card” with header text “User Information,” styled as "primary", optionally collapsible.


4. Putting It All Together

When building a tSM form:

  1. Start with a standard JSON Schema definition of your data and validation.
  2. Add the layout array to define how fields are displayed, grouped, and arranged.
  3. Use widget (and its sub-fields) on both properties and layout items to specify UI types, or the container look-and-feel.
  4. Set advanced parameters in config for custom logic, styling, or referencing external scripts or condition expressions.
  5. (Optional) Include localizationData if you support multiple languages.

The tSM rendering engine merges all these definitions and creates a dynamic form that respects both data validation (from JSON Schema) and sophisticated UI features (from layout, widget, and config).


Conclusion

TSM extends JSON Schema by adding a layout system and UI widgets. This allows developers to define the data structure and validation rules in a standard way, while simultaneously specifying how the form should be visually and functionally arranged. The result is a robust, declarative approach to building complex forms or entire pages without manually coding the UI in a traditional framework.