Form

The Form component allows grouping of multiple input-components, for example, text inputs, selects, checkboxes or switches, together in one coherent form. This component can host other child components and has its own grid. Creating forms like this has the following benefits:

  • The Form automatically contains a submit button, and can be configured to offer a secondary cancel-button

  • Validation rules are applied to all inputs of the form when it is submitted

  • All inputs of the form can be automatically cleared after a successful submit

The following sections describes these mechanisms in more detail.

Validation rules

Input components may have validation rules. These could be simple, for example, "minimum text length". Or more sophisticated, for example, custom regular expressions or even custom JavaScript actions. These validations are not applied for stand-alone components, but they are considered when a surrounding Form is submitted.

The Form component offers a special "Validate on submit" configuration option for this purpose. If this property is set to true, all validation rules of all child components will be evaluated, including those of nested containers (e.g. a Form, containing a Container, containing inputs). If even a single validation rule fails, the form submission is aborted and errors are highlighted for all affected child components. In addition, the "Required" property of all child input components is evaluated as well. Any child input with "Required" set to true, but not holding a value, also leads to a validation error.

In case "Validate on submit" is disabled, no validation rules will be evaluated and the form submission will proceed without any data checks.

Submitting a form

The Form component associates an action with the "On submit" event. This action will be executed when the submit button is pressed, and no validation error has occurred (see above).

The form submission goes through the following steps:

  1. In case the "Disable while submit" property is set to true, all child input components, the submit button and the cancel button will be disabled. Especially for long-running submit actions, this guarantees that the user is not able to modify any inputs while a submission is still ongoing, or triggering more submits.

  2. If the "Show loading while submit" property is set to true, the submit button and cancel button render a loading spinner while the submit action is running, instead of their usual button labels.

  3. The submit action is triggered, without any arguments. All subsequent steps happen only once this action run has finished.

  4. In case the submit action finished successfully, and the "Clear after submit" property is set to true, all child input components are emptied. This makes it easier to have an empty form after a successful submission.

  5. Previously disabled child input components and form buttons are now enabled again, and the buttons render their labels again instead of the loading spinner. This happens even if the submit action fails with an error.

In some cases, the submit action will not fail with an error, but you do not want to clear the form. This can be achieved by returning false in the submit action. In this case, clearing the form is skipped even when "Clear after submit" is set to true.

You must explicitly return false, and not something falsy like 0, null, undefined or an empty string.

Getting form data

Retrieving all values in a form, or filling a form with data, are common operations in many apps. Using getters and setters of each individual child input is possible, but cumbersome. For this reason, the Form component offers a convenient getter and setter for all child inputs at once.

For example, a form called addressForm has three text inputs: nameInput, streetInput and cityInput. Typically, you retrieve data with the following code:

const nameValue = nameInput.value;
const streetValue = streetInput.value;
const cityValue = cityInput.value;

A more convenient way is the following:

const formData = addressForm.getData();
// formData will be an object like this:
// {
//   nameInput: string;
//   streetInput: string;
//   cityInput: string;
// }

The result is fully typed, so that you can enjoy helpful IntelliSense support:

Fetching all values of all inputs like this is useful, but sometimes ambiguous. There are two categories of input components for which the question "What is your value?" could be answered in different ways:

  • Select / Multi-Select: These components offer two ways to retrieve their value(s): value and values.

    • values provides an array of all selected values (i.e. an empty array in case nothing is selected).

    • value provides the first selected value as primitive (i.e. null in case nothing is selected).

  • Date / Date-Time / Time: These components offer three ways to retrieve their value:

    • value: returns a JS Date or null

    • valueISOString: returns an ISO 8601 string or null

    • valueFormattedString: returns a string formatted according to the configuration properties of the input, or null

Due to this ambiguity, there is a way to explicitly declare what format to receive the data in. The getData() function of the Form API accepts an object argument to define the format for each individual child input:

const formData = addressForm.getData({
  countrySelect: {
    getterName: 'values'
  },
  registrationDate: {
    getterName: 'valueISOString'
  }
});
// formData.countrySelect is now guaranteed to be an array
// formData.registrationDate will be a string in ISO 8601 format, or null

For convenience, using this function is fully supported by the Uify type system.

Setting form data

Filling an entire form with a single method call can be done by using the setData() function of the Form API. It accepts an object argument, with names of the targeted child inputs as keys, and the values you would like to set for them as object values. Continuing the previous example of the addressForm, add the following:

addressForm.setData({
  nameInput: 'John Doe',
  streetInput: 'Main Street 1',
  cityInput: 'New York'
});

Similar to the type support of getData(), the Uify IDE offers supports when constructing such expressions:

This type support also prevents providing wrong input values (in this example, a number instead of the expected string). This validation depends on the input type.

  • A Select allows the pass of an array of selected values.

  • Date Input accepts a JS Date.

Besides the better usability, using setData is also more performant than using individual setters of each input. setDatais executed in a single, atomic state update and is synchronized to other collaborators in a single message. Using multiple setters of specific input components. however, results in a sequence of updates and messages. It is therefore strongly recommended to use the form getters and setters when possible.

Properties

The Button component offers the following configuration properties.

PropertyTypeDefault valueBehavior

Button disabled

boolean

false

Whether the submit button should be disabled or not.

Cancel button disabled

boolean

false

Whether the secondary cancel button should be disabled or not. This property is only accessible when "Show cancel button" is set to true

Cancel button text

stringWithJs

'Cancel'

Label of the secondary cancel-button. This property is only accessible when "Show cancel button" is set to true

Clear after submit

boolean

true

When set to true, all child inputs of the form are cleared after successful execution of the "On submit" action - unless it returns false. Learn more

Disable while submit

boolean

false

When set to true, all child inputs, the submit-button and the cancel-button are temporarily disabled while the "On submit" action is running. Learn more

Full width

boolean

false

When set to true, the submit and cancel button will take the entire width of the form, instead of just enough space to contain their labels.

Header text

stringWithJs

'Header'

The text to be displayed in the form header. This property is only accessible when the "Show header" property is set to true

Hide submit button

boolean

false

When set to true, the submit button is not displayed at all. This is relevant for use cases where a form should only be submitted programmatically.

Scrollable

boolean

true

Determines whether the user can scroll to overflowing content, or whether that content will be hidden.

Show cancel button

boolean

false

Whether the secondary cancel button should be displayed next to the submit button or not.

Show header

boolean

false

When set to true, the form will show a textual header, that can be configured with the "Header text" property.

Show loading while submit

boolean

true

When set to true, both the submit and cancel button display a loading spinner while the "On submit" action is running instead of their labels. Learn more

Text

stringWithJs

'Submit'

The label of the submit button.

Validate on submit

boolean

true

When set to true, all validation rules and "Required" properties of child inputs will be evaluated. In case of any validation error, the form submission will be aborted and errors will be rendered for all affected inputs. Learn more

Read the documentation of the Container component to learn more about the behavior of the "Scrollable" property, and how it differs in the app editor versus the end user experience in the workspace.

Events

The Form allows to define actions to be executed in case of two events:

  • On submit run: This action is executed when a form is submitted, i.e. when either the user clicks on the non-disabled submit button, or when the submit() function is triggered programmatically. The execution time of this action determines how long the form might be disabled and spinners might be displayed. When this action returns false, the automatic form clearing can be prevented (learn more).

  • On cancel run: This action is executed when the user clicks on the non-disabled, secondary cancel button. For this to be possible, the "Show cancel button" property must be set to true.

API

The Form exposes the following API in the JavaScript runtime environment.

Property / FunctionTypeBehavior

buttonColor

string

Provides the color of the submit button.

buttonDisabled

boolean

Provides the current boolean value of the "Button disabled" property, i.e. whether the submit button is currently disabled or not. This does not take into account potential disabling during submit.

buttonFullWidth

boolean

Provides the current boolean value of the "Full width" property.

buttonText

string

Provides the submit-button label, i.e. the current value of the "Text" property.

buttonTextColor

string

Provides the text-color of the submit button.

cancelButtonDisabled

boolean

Provides the current boolean value of the "Cancel button disabled" property, i.e. whether the cancel button is currently disabled or not. This does not take into account potential disabling during submit.

cancelButtonText

string

Provides the cancel button label, i.e. the current value of the "Cancel button text" property.

clear()

() => void

Clears all form child inputs, i.e. sets their value to "empty". The semantics of that depend on the component type.

clearOnSubmit

boolean

Provides the current boolean value of the "Clear on submit" property.

disableWhileSubmit

boolean

Provides the current boolean value of the "Disable while submit" property.

getData(options)

(options: object) => object

Provides values of all direct and nested child inputs in one object, keyed by component name. The options determine the value formats. Learn more

headerText

string

Provides the current value of the "Header text" property.

hideButton

boolean

Provides the current boolean value of the "Hide submit button" property.

reset()

() => void

Similar to clear(), however instead of making each child component empty, they are reset to their "default value". This allows to not clear the form entirely, but rather to reset it to the same default state that it had on initial app load.

showHeader

boolean

Provides the current boolean value of the "Show header" property.

showLoadingWhileSubmit

boolean

Provides the current boolean value of the "Show loading while submit" property.

setButtonColor(value)

(value: string) => void

Sets the submit button color to the provided string value.

setButtonDisabled(value)

(value: boolean) => void

Sets the "Button disabled" property to the provided boolean value.

setButtonFullWidth(value)

(value: boolean) => void

Sets the "Full width" property to the provided boolean value.

setButtonText(value)

(value: string) => void

Sets the submit button label to the provided string value.

setButtonTextColor(value)

(value: string) => void

Sets the text color of the submit button to the provided string value.

setCancelButtonDisabled(value)

(value: boolean) => void

Sets the "Cancel button disabled" property to the provided boolean value.

setCancelButtonText(value)

(value: string) => void

Sets the "Cancel button text" property to the provided string value.

setClearOnSubmit(value)

(value: boolean) => void

Sets the "Clear on submit" property to the provided boolean value.

setData(data)

(data: object) => void

Fills the form child inputs with the provided values. Learn more

setDisableWhileSubmit(value)

(value: boolean) => void

Sets the "Disable while submit" property to the provided boolean value.

setHeaderText(value)

(value: string) => void

Sets the "Header text" property to the provided string value.

setHideButton(value)

(value: boolean) => void

Sets the "Hide submit button" property to the provided boolean value.

setShowHeader(value)

(value: boolean) => void

Sets the "Show header" property to the provided boolean value.

setShowLoadingWhileSubmit(value)

(value: boolean) => void

Sets the "Show loading while submit" property to the provided boolean value.

submit()

() => Promise<void>

Submits the form, i.e. applies exactly the same logic like when the user clicks on the submit button. This triggers a sequence of events, about which you can read more here.

Last updated