Advanced Form

The advanced form was introduced to provide more flexibility when building compilations used to capture user input. It is based on the react-jsonschema-form library.

The advanced form offers many features that are not explained in detail here but are described on the library documentation pages. The live playground is also a very useful resource to interactively experiment with the various form options. Additionally, also have a look at the JSON Schema online documentation.

Model

{
    "type": "advancedform",
    "data": {},       // form field data object
    "schema": {},     // Define the structure of the form data
    "uischema": {},   // Define which input control to use when editing a field
    "formOptions": {} // Define field specific actions and styling
}

Data

Refer to the generic widget page for a description of the general principles governing the treatment of data retrieved from a dataSource

The advanced form data element is an object with structure that matches the schema definition. It can be a flat set of key-value pairs but may also contain nested complex elements. For example:

{
    "house_address": {
        "street": "7 Church Street",
        "city": "Digby"
    },
    "firstName": "Joe",
    "lastName": "Bloggs",
    "age": 27,
    "telephone": "555 123 456"
}

Schema

The schema element serves to define the structure of the form data.

{
    "type": "object",
    "definitions": {},
    "dependencies": {},
    "description": "Form description",
    "title": "Form tile",
    "required": [],
    "properties": {}
}
Field Description

definitions

The definitions property can be used to declare one or more named composite object types which are referenced when defining properties. This is particularly useful when multiple fields in the form have the same object structure. $ref is used to reference the declared definitions (See address field in the example below)

Note: If a particular object field only appears once in the form, the nested structure can be declared in situ by directly providing the object properties.

description

Optional description, shown after the title.

dependencies

Used to define inter-field dependencies.

properties

Contains the declarations for the named form fields. They are always nested in schema elements of type "object". Refer to the properties section below for more detail.

readonly

Render all the fields in the form read-only. Individual fields can be be made readonly by using the ui:readonly property

required

List of required fields which must have a value before the form can be submitted. Required fields without appropriate values will be shown with a red border when a submit is attempted.

The entries in the list refer to fields at the current object level. If the form contains nested fields, such as street and city in the example above, and these are required, then the property must be included at the schema level where they are declared as shown in the example below.

title

Optional form title shown at the top of the form.

type

Defines the top level type of form data and needs to be of set to object

Properties

The properties element, inside the schema section, is used to declare named fields shown on the form and save in the data. At the schema level it defines the root data properties, which may in turn be complex objects containing their own properties.

Each property needs a type and may be further qualified using a number of available attributes, some of which are highlighted in the table below:

Field Description

allOf, anyOf, oneOf

These properties allow different elements of a schema to be selected from an array of possibilities providing a means to dynamically control which fields ultimately appear in the data. When using oneOf or anyOf a specific field is typically configured to make the selection of the schema structure to activate and will be shown as a dropdown letting the user choose the fields to populate. The ui:widget for this field should therefor be set to "select" in the uischema.

default

Optional default value to assign if none is provided.

definitions

The definitions property can be used to declare one or more named composite object "types". This is particularly useful when multiple fields in the form have the same object structure. $ref is used to reference the definitions from a property (See address field in the example below)

Note: If a particular object field only appears once in the form, the nested structure can be declared in situ by directly providing the object properties.

description

Optional field description, shown after the title.

dependencies

Used to define inter-field dependencies.

enum

Enumeration used to define selectable options for a field. Note: When using enum fields be sure to select the appropriate ui:widget in the uischema.

enumNames

Custom labels used to provide readable names for numeric enum fields.

items

Defines the type of elements in array fields. This can be a simple type such as string or number, etc or it can be a composite type containing other fields. (refer to the Nested and Array examples live playground for more detail)

properties

Named properties of the root or nested form elements of type "object".

Note that the fields appear on-screen in the same order as they do in the properties section. The order can be explicitly set in the uischema using the ui:order property.

Refer to the library documentation for more details.

title

The field title is optional. If it is not provided, the field name (key) is used as the title.

type

Defines the type of the enclosing element. The root element must be of type object since it contains all the form fields. Individual form fields can have any of the following types:

  • array: Used for lists of data. Needs to have an items property set to declare the type of the array elements. (also see uischema for matching input controls.)

  • boolean: True/False value. Will be rendered as a check-box by default.

  • integer: Whole numbers. The form will do type validation to check that the provided input is an integer number.

  • number: Any number including decimals. The form will do type validation to check that the provided input is a integer or real number.

  • null: "dummy" entry used to provide extra information to form users. Null fields don’t present an input field nor do they appear in the data.

  • object: Object with named fields. Fields are declared in the properties of the enclosing object. (see example below)

  • string: Generic text input. Note that date fields need to be declared as strings since they are stored in ISO 8601 strings format.

The field type can also be an array of two elements. One being the base type, the other "null" if the field in question is nullable. (For example “type”: ["integer", "null"]). Since a null cannot be entered, the field default would also need to be set to null.

uniqueItems

Apply this property to array type fields to ensure that a specific entry can only be selected once.

Schema Examples

Definition and reference

In this example a number of schema options are shown. Note the use of definitions to define the address object with two fields and its use in the house_address field by referring to it with a $ref path.

{
    "type": "object",
    "required": [
        "firstName",
        "lastName",
        "age"
    ],
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "street": {
                    "type": "string",
                    "title": "Street"
                },
                "city": {
                    "type": "string",
                    "title": "City"
                }
            },
            "required": [
                "street",
                "city"
            ]
        }
    },
    "properties": {
        "firstName": {
            "type": "string",
            "title": "First name"
        },
        "lastName": {
            "type": "string",
            "title": "Last name"
        },
        "age": {
            "type": "number",
            "title": "Age",
            "minimum": 18,
            "maximum": 67
        },
        "birth_month": {
                "type": "integer",
                "title": "Month of Birth",
                "enum": [1,2,3,4,5,6,7,8,9,10,11,12],
                "enumNames": [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
                ]
        },
        "telephone": {
            "type": "string",
            "title": "Telephone",
            "minLength": 10
        },
        "house_address": {
            "type": "object",
            "title": "House Address",
            "$ref": "#/definitions/address"
        },
        "email": {
            "type": "string",
            "title": "Email",
            "format": "email"
        }
    }
}

Composite array values

In this schema, the input field, called tuples, is an array containing objects with a name and a value declared directly in the property, rather than using a definition and reference as in the example above:

{
    "type": "object",
    "properties": {
        "tuples": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "value": {
                        "type": "number",
                        "enum": [ 1, 2, 3, 4 ]
                    }
                }
            }
        }
    }
}

Refer to the uiSchema example to see how to set the input controls to use for each of the fields.

Schema validation properties

The following schema validation properties are provided in the schema section of the form. Also refer to the uischema for additional validation options.

Field Description

exclusiveMinimum, exclusiveMaximum

Validate number to be strictly larger than or less than the stated minimum or maximum

exclusiveMinimum < Field Value < exclusiveMaximum

format

Allows a set of pre-defined schema formats to be used to validate strings. The Advanced Form supports the standard JSON Schema formats and adds two extra custom formats as defined here

minimum, maximum

Enable validation on the allowed values of integer and number field

minimumField Valuemaximum

maxItems, minItems

Set limits on the number of elements allowed in an array field.

maxLength, minLength

Set limits on the allowed length of a string property

multipleOf

Constrain the numeric field value to be a multiple of the multipleOf property, for example:

{
    "type": "number",
    "multipleOf" : 10
}

pattern

Validation regular expression to applied to string fields. Patten validation is only done on fields which contain data. This implies that to enforce patterns which require the text to contain a minimum number of characters, the field must also be required.

UI Schema

The UI Schema is used to manage the appearance of the form fields and specify which controls to use to edit them. It is recommended that a ui:widget be assigned to all form fields to ensure the edit controls used adhere to the overall styling of the WebStudio compilation and the selected theme.

The uiSchema property contains elements for all form-fields requiring configuration to be applied, the model for which looks something like this:

{
    "ui:order" : [] // Optional array used to set the display order of the form fields
    "<field-name>": { // Entry for each field requiring ui-configuration
        "<ui:xxx>" : "value" // See table below for available options
        "<nested-field-name>": {
            // configuration detail for fields in nested objects.
        }
    }
}

The angle brackets in the above fragment are used to indicate placeholders for implementation specific content.

Field Description

classNames

String field containing the names of one or more style classes to assign to the field. Refer to formOptions.styleByClassName for more details.

ui:description

Alternative / override field description. This one takes precedence over the description in the schema

ui:disabled

Set to true to disable the field and prevent the content from being selected. This setting on the face of it does the same as ui:readonly, the difference is that the latter still allows the content to be selected.

ui:enumDisabled

This array property can be used to disable one or more options from an enum list. For example:

{
    "schema" : {
        "enumField": {
            "type" : "string",
            "enum" : ["One", "Two", "Three"]
        }
    },
    "uiSchema" : {
        "enumField": {
           "ui:enumDisabled" : ["Two"]
        }
    }
}

ui:help

Display an additional help string after the field input control.

ui:options

This is a composite property with the following fields:

inline

when set to true, radio buttons and check-boxes can be shown in-line rather than on separate lines. For example, using an array field to allow users to select multiple options, the following setting could be used:

{
    "schema": {
        "type": "object",
        "properties": {
            "hobbies": {
                "type": "array",
                "title": "Hobbies",
                "description": "Check all that apply",
                "items": {
                    "type": "string",
                    "enum": [ "sports", "camping", "travel", "reading", "making" ]
                },
                "uniqueItems": true
            }
        }
    },
    "uiSchema": {
        "hobbies": {
            "ui:widget": "checkboxes",
            "ui:options": {
                "inline": true
            }
        }
    }
}

inputType

Note: Not all the options from the underlying library have been fully integrated with WebStudio yet. These will be documented as they are introduced.

  • color: The input control used for the field is a color-picker

  • file: Allows a file name to be picked from the local file system. The field name will be the path to the selected file.

  • password: Causes the field text to be obscured. Don’t set the ui:widget property with this setting yet.

  • text: Treat the input as a regular text box.

label

Setting the label property to false will cause the field name to be hidden.

placeholder

Place-holder text shown in the input box to provide users with a hints of the expected content.

rows

Used with a "textarea" ui:widget type, sets the number of rows in the edit box.

ui:placeholder

This is the same as the placeholder in the options field.

ui:readonly

When set to true, the field value cannot be edited but is still selectable and can be copied to the clipboard.

ui:title

Overrides the field title provided in the schema section

ui:widget

This property is used to select the specific widget to use as the input control for the field. Available options are:

  • checkbox: Shows a single checkbox, typically used with a boolean field.

  • checkboxes: Shows a set of check-boxes. Can be used with array properties where multiple selections are made from an enum as shown in the inline example above.

  • datepicker: Provides an input box with an icon to bring up a date-time picker dialog.

  • hidden: Hides the field in the form.

  • password: Obfuscates entered characters. The same outcome can be achieved by setting the inputType equal to password

  • radio: Shows a radio-button associated with boolean or single selectable enum value. In case of the latter one radio button is shown for each enumeration.

  • range: Shows a range slider. The minimum and maximum values for the slider are taken from the schema minimum and maximum settings.

  • select: Drop-down list. When this ui:widget is used with properties of type array, multiple items can be selected.

  • text: Text input box

  • textarea: Shows a multi-line text input field

  • updown: Input field restricting the values that can be entered to a number, either integer or decimal.

uiSchema examples

Nested Fields:

Referring to the "Definition and Reference" example above, the uiSchema to set the address input controls for the street to a text-box and the city to a regular input would look something like this.

{
    "house_address": {
        "street": {
            "ui:widget": "textarea"
        },
        "city": {
            "ui:widget": "text" // Not really needed since string fields use this widget by default
        }
    }
}

The outer object name used is that of the containing field "house_address", rather then the type "address"

Nested fields in an array:

When the fields are contained in an array as is the case for the second schema example and require specific ui:widget specs, an items element needs to be added to the specification as shown:

{
    "tuples": {
        "items": {
            "name": {
                "ui:widget": "text"
            },
            "value": {
                "ui:widget": "select"
            }
        }
    }
}

Form Option

The form options provide further customization features that are specific to WebStudio. The formOptions property has the following structure:

{
    "formOptions" : {
        "entryOptions": {
            "<field-name>" : {
                "actions": { }
            }
        },
        "styleByClassName": {
            "<custom-class-name>" : { }
        }
    }
}
Field Description

entryOptions

Action pipelines can be triggered on changes to individual fields. To do so, add the field-name as a key under the entryOptions element and implement the desired pipeline in the relevant actions entry. Fox example, say we wanted to perform some action when the firstName field gets the input focus.

{
    "formOptions" : {
        "entryOptions": {
            "firstName" : {
                "actions": {
                    "onFocus" : {
                        "type" : "notify"
                    }
                }
            }
        }
    }
}

The actions available at field level are: onBlur, onChange, onChanged and onFocus.

Field level actions for nested entries can be declared by providing the dot-notation path. Consider a form with the following schema:

{
"schema": {
        "type": "object",
        "properties": {
            "nested": {
                "type": "object",
                "properties": {
                    "field1": {
                        "type": "string",
                        "title": "Field 1"
                    }
                }
            }
        }
    }
}

To define an action pipeline to trigger when field1 gets the input focus, the entryOptions would look like this:

{
    "formOptions": {
        "entryOptions": {
            "nested.field1": {
                "actions": {
                    "onFocus": {
                        "type": "notify"
                    }
                }
            }
        }
    }
}

styleByClassName

This property is used to add custom styling to form fields. Let’s say for some fields in the form we want to use a different font. The style can be declared as follows:

  • In the formsOptions.styleByClassName add a property for the custom class name, let’s call it customFontClass. Add the style options in the style body.

  • In the uischema, include a classNames property with all fields where we want the new style to be applied and set the value to customFontClass

{
    "schema": {
        "type": "object",
        "properties": {
            "monoTextField": {
                "type": "string"
            }
        }
    },
    "uiSchema": {
        "monoTextField": {
            "ui:widget": "textarea",
            "classNames": "customFontClass",
            "ui:title": "Mono-space Text Field"
        }
    },
    "formOptions": {
        "styleByClassName": {
            "customFontClass": {
                "fontFamily": "Monaco",
                "fontSize": "larger"
            }
        }
    }
}

showValidationErrors

Validation error can be shown directly as annotations in the form by setting this property to true, or suppressed entirely by setting it false

Options

Set widget options.

{
    "options": {
        "showRefreshButton": true,
        "showToolbar": false,
        "refreshInterval": 10
    }
}
name description

showRefreshButton

Set this to false to hide the refresh button. By default the refresh button is visible.

showToolbar

Use to hide the complete toolbar.

refreshInterval

Refresh with an interval in seconds.

Actions

The Advanced Form supports a number of action hooks in addition to the default lifecycle ones, most of which can be used at form and field level by defining entryOptions as described above. The exceptions are onSubmit and onValidationError, which are not triggered separately for each field.

The Advanced Form actions are:

  • onBlur : This event fires whenever a field loses input focus.

  • onChange : Triggers on every input change.

  • onChanged : The action only triggers if the content of the field, when it loses input focus, is different from that when it received focus.

  • onFocus : Triggers when a field receives input focus.

    The message payload for these actions contains the name of the affected field expressed, in dot-notation if it is nested, and optionally the current value. The value is omitted if the field is blank. For example:

    {
        "payload": {
            "name": "nested.field1",
            "value": "some text"
        }
    }
  • onSubmit : Gets called when the form submit button is pressed. The submit will not fire if there are validation error on the page.

    When the form is valid, the message payload will be the form data object. Only fields containing values will be present in the output.

  • onValidationError : Triggers when the form is submitted but there are validation errors.

    The message payload in this case is an array of error messages for all invalid fields.

Collect

The collect action can be used in an action pipeline to retrieve the current form data. The message payload will contain an object with entries for all fields that have a valid value.