Skip to content
Backlit
Esc
navigateopen⌘Jpreview

Lookup definition

Return fields and records for search and options inputs.

Register a lookup with resource.lookup(name, resolver) or resource.lookup(name, { params }, resolver). A name must be unique within its resource. The resolver receives ctx and a LookupBuilder.

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

import { countries, countryPicker } from './countries.ts'
import { states, statePicker } from './states.ts'

const country = fields.ref('country', () => countries, {
  label: 'Country',
  display: 'name',
  inputVariant: optionsVia(countryPicker, {
    value: 'code',
    label: 'name',
  }),
})

const state = fields.ref('state', () => states, {
  label: 'State',
  display: 'name',
  inputVariant: optionsVia(statePicker, [country], {
    value: 'code',
    label: 'name',
  }),
})

const orders = defineResource('orders', [country, state])

const placeOrder = orders.action(
  'place',
  z.object({ country: z.string(), state: z.string() }),
  () => {}
)

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

  return formBuilder.setContent([
    formBuilder.fields(...orders.pick('country', 'state')),
  ])
})

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "create",
    "slots": {
      "content": [
        {
          "kind": "form",
          "target": {
            "resource": "orders",
            "action": "place"
          },
          "slots": {
            "content": [
              {
                "kind": "form-fields",
                "fields": [
                  {
                    "kind": "ref",
                    "name": "country",
                    "label": "Country",
                    "display": {
                      "kind": "text",
                      "name": "name",
                      "label": "Name"
                    },
                    "inputVariant": {
                      "kind": "options",
                      "lookup": {
                        "kind": "lookup",
                        "resource": "countries",
                        "name": "picker"
                      },
                      "value": "code",
                      "label": "name"
                    }
                  },
                  {
                    "kind": "ref",
                    "name": "state",
                    "label": "State",
                    "display": {
                      "kind": "text",
                      "name": "name",
                      "label": "Name"
                    },
                    "inputVariant": {
                      "kind": "options",
                      "lookup": {
                        "kind": "lookup",
                        "resource": "states",
                        "name": "byCountry",
                        "args": [
                          {
                            "path": "country"
                          }
                        ]
                      },
                      "value": "code",
                      "label": "name"
                    }
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Read search text from ctx.searchQuery and parameters from ctx.paramValues. Return lookup.setFields(fields).withData(rows). Use setRoles(map) to select field roles and onDefect(reporter) to handle invalid values. The default role is display. Extra record keys do not travel in the response.

The SDK does not query your data store or filter records automatically. A search input sends the typed query. An options input sends an empty query. The host calls app.handleLookup(resource, name, query, args) for both.

Use lookupVia or optionsVia to connect an input to the definition. Both check the selected value and label field names. Supply an argument for every parameter. Field arguments read the current form or repeater row. See Lookup targets.

The definition exposes resource, name, and params. Its resolve(ctx) method returns a success response containing the lookup fields and data. Use the app method when middleware and address checks must run.

Was this page helpful?