Skip to content
Backlit
Esc
navigateopen⌘Jpreview
On this page

Form fields

Add ordered fields to a form and place related fields on one line.

A form-fields block is one ordered run of fields inside a form. Each field submits its value under its resource-field name. The action schema checks the available names and value types at compile time.

Create this block through form.fields. It has no separate factory.

API

form.fields(...fields: FieldBuilderContract[]): FormFieldsBuilder
Method Input Result
peers ...FieldName[][] Replaces the sets of fields that share a line.

A field that is not in a peer set stands alone. The renderer controls field width and responsive placement.

Basic fields

Pass fields in display order. Use resource.pick to select existing resource fields without declaring them again.

import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'

const orders = defineResource('orders', [
  fields.text('customerName', { label: 'Customer' }),
  fields.number('quantity', { label: 'Quantity' }),
  fields.date('placedAt', { label: 'Order date' }),
  fields.boolean('expedited', { label: 'Expedited' }),
])

const createOrder = orders.action(
  'create',
  z.object({
    customerName: z.string(),
    quantity: z.number(),
    placedAt: z.string(),
    expedited: z.boolean(),
  }),
  () => {}
)

orders.view('create', () => {
  const formBuilder = form(createOrder)

  return formBuilder.setContent([
    formBuilder.fields(
      ...orders.pick(
        'customerName',
        'quantity',
        'placedAt',
        'expedited'
      )
    ),
  ])
})

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "create",
    "slots": {
      "content": [
        {
          "kind": "form",
          "target": {
            "resource": "orders",
            "action": "create"
          },
          "slots": {
            "content": [
              {
                "kind": "form-fields",
                "fields": [
                  {
                    "kind": "text",
                    "name": "customerName",
                    "label": "Customer"
                  },
                  {
                    "kind": "number",
                    "name": "quantity",
                    "label": "Quantity"
                  },
                  {
                    "kind": "date",
                    "name": "placedAt",
                    "label": "Order date"
                  },
                  {
                    "kind": "boolean",
                    "name": "expedited",
                    "label": "Expedited"
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Peer fields

Call peers with one set of related field names. Other fields in the block remain on separate lines.

import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'

const orders = defineResource('orders', [
  fields.text('firstName', { label: 'First name' }),
  fields.text('lastName', { label: 'Last name' }),
  fields.text('email', { label: 'Email' }),
])

const createOrder = orders.action(
  'create',
  z.object({
    firstName: z.string(),
    lastName: z.string(),
    email: z.email(),
  }),
  () => {}
)

orders.view('create', () => {
  const formBuilder = form(createOrder)

  return formBuilder.setContent([
    formBuilder
      .fields(
        ...orders.pick('firstName', 'lastName', 'email')
      )
      .peers(['firstName', 'lastName']),
  ])
})

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "create",
    "slots": {
      "content": [
        {
          "kind": "form",
          "target": {
            "resource": "orders",
            "action": "create"
          },
          "slots": {
            "content": [
              {
                "kind": "form-fields",
                "fields": [
                  {
                    "kind": "text",
                    "name": "firstName",
                    "label": "First name"
                  },
                  {
                    "kind": "text",
                    "name": "lastName",
                    "label": "Last name"
                  },
                  {
                    "kind": "text",
                    "name": "email",
                    "label": "Email"
                  }
                ],
                "peers": [
                  [
                    "firstName",
                    "lastName"
                  ]
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Multiple peer sets

Pass more than one set to create multiple peer rows. Calling peers again replaces all previous sets.

import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'

const orders = defineResource('orders', [
  fields.text('firstName', { label: 'First name' }),
  fields.text('lastName', { label: 'Last name' }),
  fields.text('email', { label: 'Email' }),
  fields.text('phone', { label: 'Phone' }),
  fields.text('note', { label: 'Order note' }),
])

const createOrder = orders.action(
  'create',
  z.object({
    firstName: z.string(),
    lastName: z.string(),
    email: z.email(),
    phone: z.string(),
    note: z.string(),
  }),
  () => {}
)

orders.view('create', () => {
  const formBuilder = form(createOrder)

  return formBuilder.setContent([
    formBuilder
      .fields(
        ...orders.pick(
          'firstName',
          'lastName',
          'email',
          'phone',
          'note'
        )
      )
      .peers(['firstName', 'lastName'], ['email', 'phone']),
  ])
})

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "create",
    "slots": {
      "content": [
        {
          "kind": "form",
          "target": {
            "resource": "orders",
            "action": "create"
          },
          "slots": {
            "content": [
              {
                "kind": "form-fields",
                "fields": [
                  {
                    "kind": "text",
                    "name": "firstName",
                    "label": "First name"
                  },
                  {
                    "kind": "text",
                    "name": "lastName",
                    "label": "Last name"
                  },
                  {
                    "kind": "text",
                    "name": "email",
                    "label": "Email"
                  },
                  {
                    "kind": "text",
                    "name": "phone",
                    "label": "Phone"
                  },
                  {
                    "kind": "text",
                    "name": "note",
                    "label": "Order note"
                  }
                ],
                "peers": [
                  [
                    "firstName",
                    "lastName"
                  ],
                  [
                    "email",
                    "phone"
                  ]
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Wrap a form-fields block in a panel or section when the fields need a heading, description, or visible surface. See Form for form composition and initial values.

Field roles

setRoles({ fieldName: role }) selects roles for individual fields and replaces the previous selections. The default role is display in tables and datalists, and input in form field blocks. See Field roles.

revealWhen(condition) controls the complete block. See Form conditions.

Was this page helpful?