Advanced topics
Form scripts

Form scripts

With LetsForm changing the fields or the behaviour of a form (i.e., disabiling a field, etc.) it's just a matter of changing the form schema (see the Helpers section).

These changes can also be implemented using JavaScript snippets: small chunk of JavaScript codes to apply changes in the form schema, for example in this simple form with just a checkbox and an input field

const MY_FORM = {
  version: 2,
  fields: [
    { name: 'myCheckbox', component: 'checkbox', label: 'Enable the input' },
    { name: 'myText', component: 'input-text', label: 'My text field', disabled: true }
  ],
  script: `
    if (myCheckbox) {
      enable('myText');
    } else {
      disable('myText');
    }
  `
}

In this case the form script enables or disables the text field if the checkbox is checked.

A form script defined at the root of the form is executed at every render of the form and after every field changes (thanks to react-hook-form the form component doesn't re-render is a field changes). A form script defined inside a field, is executed only if the field changes and at first render of the form, the example above can be rewritten as

const FORM = {
  version: 2,
  fields: [
    {
      name: 'myCheckbox',
      component: 'checkbox',
      label: 'Enable the input',
      script: `
        if (myCheckbox) {
          enable('myText');
        } else {
          disable('myText');
        }
        `
    },
    {
      name: 'myText',
      component: 'input-text',
      label: 'My text field',
      disabled: true
    }
  ]
}

In this case the JavaScript code is executed only if the field myCheckbox changes value, as opposed as the example before where any changes in the field myText causes the code to be evaluated after every changes.

The form scripts are wrapped into an async generator with some context helper methods (i.e. hide(), enable(), ...) that make easier to apply changes to the form schema. That means that is possible to implement asynchronous operations and apply the result to the form, for example fetching some remote data to populate the drowndown of a select component

// ... a field in a form schema
{
  name: 'my_field',
  // ...
  script: `
    disable('my_select');
    yield();
    const res = await fetch('http://some-remote-data');
    const options = // do something clever here with the received data
    setValue('my_select', 'options', options);
    enable('my_select');
  `
}

In that case, when the my_field changes, the combobox named my_select is disabled, then some data is fetched from an external resource and transformed in a proper array of options for a combobox, then applied to the select component and finally the combo box is enabled again.

💡

Helpers like disable(), enable(), etc execute changes to the form schema which are only applied when the form script ends, to apply before the end of the execution add the instruction yield();, it returns and apply all intermediate changes of the form schema to the current view.

Example with fetch

Another simple example is a text-field with input-type="color" property which fetch the color name as soon as the user selects something.

The JSON schema for the field

{
  "component": "input-text",
  "label": "Select color",
  "name": "color",
  "react-rsuite5": {
    "fullWidth": false,
    "width": 200
  },
  "hint": "Name: Forest Green",
  "script": "<---see below--->",
  "inputType": "color"
}

The script just uses the hint field to show the name of the current selected color (using public API from www.thecolorapi.com (opens in a new tab)).

if (typeof color !== 'string') {
  // just clear if anything different from a string is selected
  setValue('color', 'hint', '');
  return;
}
// cleanup
const colorExa = color.substring(1);
// async fetch from color API
const res = await fetch(`https://www.thecolorapi.com/id?format=json&hex=${colorExa}`);
const colorInfo = await res.json();
// update the "hint" value of the field "color"
setValue('color', 'hint', `Name: ${colorInfo.name.value}`);

This example is available in the Form templates section.

Methods

setValue(fieldName, propertyName, value) Deprecated, same as .setParam()

setParam(fieldName, propertyName, value) Change a parameter of a specific field of the form (referenced by name property).

setParam('my_field', 'placeholder', 'Insert name');

setFieldValue(fieldName, value) Programmatically set a value of a field, will cause re-render of the field component

setFieldValue('my_field', 'my value');

arraySetParam(arrayFieldName, fieldName, key, value) Change a parameter of a specific field of an array in the form (referenced by field name properties).

arraySetParam('my_array', 'my_field_in_the_array', 'placeholder', 'Insert name');

arraySetValue(arrayFieldName, fieldName, key, value) Deprecated, same as .arraySetParam()

element(fieldName) Returns the DOM element which contains a field in the form (referenced by name property).

element('my_field').style.marginTop = '20px';

style(fieldName, cssProp, value) | style(fieldName, cssProps) Apply CSS properties to the element which contains a field in the form (referenced by name property).

style('my_field', 'marginTop','20px');
// or using an object as secondo argument
style('my_field', {
  marginTop: '20px',
  marginBottom: '20px
});

css(selector, cssProps) Apply CSS properties to the elements identified by the selector (i.e. ".group div") inside the DOM element which contains a field in the form.

css('.hint p', { marginTop: '20px' });

enable(fieldName) Enable a field in the form (referenced by name property).

enable('my_field');

disable(fieldName) Disable a field in the form (referenced by name property).

enable('my_field');

hide(fieldName) Hide a field in the form (referenced by name property).

enable('my_field');

show(fieldName) Show a field in the form (referenced by name property).

enable('my_field');

toggle(fieldName, propertyName) Toggle a boolean value on a field in the form (referenced by name property).

toggle('my_field', 'disabled');

context(key) Get a key from the form context (see context property in LetsForm props)

const token = context.get('token');

my_field1...my_fieldN The current value of a field is available (as read-only objects), for example if my_field is a checkbox field

if (my_field) {
  enable('my_other_field');
}

or if my_field is a input-text field

if (my_field !== '') {
  show('my_other_field');
}

values A read-only hash with all current values of the form. For example if my_field is a checkbox field

if (values.my_field) {
  enable('my_other_field');
}

or if my_field is a input-text field

if (values.my_field !== '') {
  show('my_other_field');
}

Explore the available properties for each field by clicking in the icon {} in the top right corner of the LetsForm Designer field tab.