Forms

Validation

Five props cover almost everything, and the sixth is a function for when they do not.

The five

on a field
{
  key: "email",
  label: "Email",
  editable: true,
  required: true,                       // 1. must be filled
  pattern: "^[^@\s]+@[^@\s]+$",        // 2. must match
  patternMessage: "That is not an email address",
  trim: true,                           // 3. whitespace is not a value
},
{
  key: "seats",
  label: "Seats",
  editable: true,
  min: 1,                               // 4. and 5.
  max: 500,
}

patternMessage matters more than it looks. Without it a reader gets the pattern, and a regular expression is not an error message.

Your own rule

validate receives the value and the whole row, so a rule can depend on another field. Return a string to fail with that message, or nothing to pass.

a cross-field rule
{
  key: "endsAt",
  label: "Ends",
  editable: true,
  format: "date",
  validate: (value, row) =>
    value && row.startsAt && value < row.startsAt
      ? "The end date is before the start date"
      : undefined,
}

Where the message appears

Under the field, as text. Set form: { errorDisplay: "tooltip" } on the provider for a tooltip instead, which suits a dense form where a line of text under every field would double its height.

When it did not work

A required field submits empty

Cause: the value is whitespace, and whitespace is a value. Fix: trim: true. Verify: a space no longer satisfies it.

The rule never runs

Cause: the field is not editable, so it is display only and there is nothing to validate. Fix: mark it editable, or move the rule to the field that is.

min and max do nothing

Cause: they are numeric bounds, and the value is a string. Fix: store the number, or use validate.