Skip to content

Schema

This page provides a comprehensive reference for all schema types used in EnformaJS.

Basic Schema Example

js
const schema = {
  // FIELDS
  name: {
    type: 'field',
    label: 'Name',
    // ... more details go here
    section: 'personal_info'
  },
  email: {
    type: 'field',
    label: 'Email',
    // ... more details go here
    section: 'personal_info'
  },
  friends: {
    type: 'repeatable_table',
    subfields: {
      // details
    }
  },
  personal_info: {
    type: 'section',
    title: 'Personal details'
  }
}

Common Schema Properties

All schema types share these base properties:

PropertyTypeRequiredDescription
typestringYesType of schema: 'field', 'section', 'repeatable', or 'repeatable-table'.
componentstringNoThe component used for rendering this part of the form. If not provided, the components provided via configuration will be used
sectionstringNoThe section this schema belongs to
positionnumberNoPosition for rendering in the form/parent section
ifstringNoConditional expression to determine if this part of the should be shown

IMPORTANT

Use the component for customizing the rendering of the form. For example if you have a special repeatable table make your own component like <OrderItemsTable/>. See more on Integrating Custom Components

Field Schema

PropertyTypeRequiredDescription
labelstringNoLabel text for the field
hideLabelbooleanNoShould hide the label from the field
showLabelNextToInputbooleanNoFor checkbox-like inputs
helpstringNoHelp text to display alongside the field
requiredboolean | stringNoWhether the field is required (UI purposes only)
useModelValuebooleanNoWhether to use update:modelValue event instead of input/change events (default: false)
propsobjectNoProps to apply to the entire field component (wrapper)
labelPropsobjectNoProps to apply to the label component
inputPropsobjectNoProps to apply to the input component
helpPropsobjectNoProps to apply to the help text component
errorPropsobjectNoProps to apply to the error message component
inputComponentstring | componentNoComponent to use for this field
rulesstringNoValidation rules for this field in string format (e.g., "required|email|min_length:6")
messagesobjectNoCustom validation messages for this field (e.g., { required: "Email is required", email: "Invalid email format" })

useModelValue

IMPORTANT

This prop is required by the input components that do not expose input and change events and instead use update:modelValue. Vuetify and Quasar do this for all their form components

This changes the way fields are marked as dirty which, in turn, determines when validation is triggered.

The ideal UX for validating a form field is the following: the field is validated after the user is done changing the field for the first time (i.e. on change) and everytime it changes the field afterward (i.e. on input).

However, when you are using update:modelValue the field must be validated on every change.

Use useModelValue to ensure the proper events are bound to the input when input and change events are not enough.

Repeatable Schema

PropertyTypeRequiredDescription
subfieldsobjectYesThe definition of fields within each repeatable item
minnumberNoThe minimum number of items allowed
maxnumberNoThe maximum number of items allowed
propsobjectNoProps to apply to the repeatable container
defaultValueanyNoDefault value when adding a new item in the array
allowAddbooleanNoWhether to show the add button (defaults to true)
allowRemovebooleanNoWhether to show the remove button (defaults to true)
allowSortbooleanNoWhether to show the move up/down buttons (defaults to true)
validateOnAddbooleanNoWhether to validate the field when a new item is added (defaults to true)
validateOnRemovebooleanNoWhether to validate the field when an item is removed (defaults to true)

Repeatable Table Schema

PropertyTypeRequiredDescription
subfieldsobjectYesThe definition of fields within each repeatable item
minnumberNoThe minimum number of items allowed
maxnumberNoThe maximum number of items allowed
propsobjectNoProps to apply to the repeatable container
defaultValueanyNoDefault value when adding a new item in the array
allowAddbooleanNoWhether to show the add button (defaults to true)
allowRemovebooleanNoWhether to show the remove button (defaults to true)
allowSortbooleanNoWhether to show the move up/down buttons (defaults to true)
validateOnAddbooleanNoWhether to validate the field when a new item is added (defaults to true)
validateOnRemovebooleanNoWhether to validate the field when an item is removed (defaults to false)

Section Schema

PropertyTypeRequiredDescription
titlestringYesTitle of the section
titleComponentstringNoTag/component used for title
titlePropsobjectNoProps to be passed to the title

Sections can contain both fields and sections.

WARNING

The fields are rendered before the sub-sections. If you want to render fields last, you must assign them to a sub-section in the last position. If you want to alternate fields with sub-sections you have to use only sub-sections

Validation Rules in Schema

As an alternative to providing validation rules through the rules prop, Enforma allows you to embed validation rules directly within your schema definition. This approach keeps validation logic close to field definitions and simplifies form configuration.

WARNING

The rules and messages attributes work only when using Encola Validator. If you are using Zod, Yup or Valibot you have to pass the validator object to the form that you have to construct separately. You might want to create your own createXYZValidatorFromSchema() function if the form schema is passed from the server as a JSON

Defining Rules in Schema

Each field in your schema can include a rules property with validation rules in string format:

js
const schema = {
  email: {
    type: 'field',
    label: 'Email Address',
    rules: 'required|email',
  },
  password: {
    type: 'field',
    label: 'Password',
    rules: 'required|min_length:8|password',
  },
  age: {
    type: 'field',
    label: 'Age',
    rules: 'required|integer|gte:18|lte:120',
  }
}

// No need to define rules separately
const formProps = {
  data: {
    email: '',
    password: '',
    age: null
  },
  schema,
  // rules prop is not needed when using schema-based validation
  customMessages: {
    'age.gte': 'Must be at least 18 years old'
  }
}

Rules in Repeatable Fields

For repeatable and repeatable-table fields, validation rules can be added to the subfield definitions:

js
const schema = {
  experiences: {
    type: 'repeatable',
    subfields: {
      title: {
        type: 'field',
        label: 'Job Title',
        rules: 'required|min_length:3'
      },
      years: {
        type: 'field',
        label: 'Years of Experience',
        rules: 'required|numeric|gte:0'
      }
    }
  },
  skills: {
    type: 'repeatable_table',
    subfields: {
      name: {
        type: 'field',
        label: 'Skill',
        rules: 'required'
      },
      level: {
        type: 'field',
        label: 'Proficiency Level',
        rules: 'required|in_list:beginner,intermediate,advanced,expert'
      }
    }
  }
}

Caveats

Multi-input fields require special attention

Fields will multiple inputs require defining special validation rules.
In the schema form example we have only the field salary for inputs salary.min and salary.max.
The example shows the rules are specified for the individual components. If you were to try to use the rules attribute of the schema you would need to create a custom validation rule, probably something like rules: "required|numeric_rage"

Custom Messages in Schema

In addition to validation rules, you can define custom error messages directly in your schema. This keeps error messages close to field definitions and makes forms more maintainable.

Defining Messages in Field Schema

Each field can include a messages object that maps rule names to custom error messages:

js
const schema = {
  email: {
    type: 'field',
    label: 'Email',
    rules: 'required|email',
    messages: {
      required: 'Email address is required',
      email: 'Please enter a valid email format'
    }
  },
  age: {
    type: 'field',
    label: 'Age',
    rules: 'required|integer|gte:18',
    messages: {
      required: 'Age is required',
      integer: 'Age must be a whole number',
      gte: 'You must be at least 18 years old'
    }
  }
}

Messages in Repeatable Fields

For repeatable and repeatable-table fields, messages can be defined in the subfield definitions:

js
const schema = {
  languages: {
    type: 'repeatable',
    subfields: {
      name: {
        type: 'field',
        label: 'Language',
        rules: 'required',
        messages: {
          required: 'Language name is required'
        }
      },
      proficiency: {
        type: 'field',
        label: 'Level',
        rules: 'required|in_list:beginner,intermediate,advanced',
        messages: {
          required: 'Please select a proficiency level',
          in_list: 'Invalid proficiency level'
        }
      }
    }
  }
}

Released under the MIT License