Web Forms

Search select fields

Searchable dropdown fields with typeahead filtering — including variants that query a GraphQL API via Apollo Client.


SearchSelect

A searchable single-select dropdown. Users can type to filter through options.

FormFieldClass.searchSelect('assignee', {
  label: 'Assign To',
  required: true,
  placeholder: 'Search team members...',
  options: [
    { value: 'user-1', label: 'Alice Johnson' },
    { value: 'user-2', label: 'Bob Smith' },
    { value: 'user-3', label: 'Carol Williams' },
    // ...potentially hundreds of options
  ],
})

SearchSelect-specific options

OptionTypeDefaultDescription
optionsSelectOption[][]Array of { value, label } objects
placeholderstring'Search...'Placeholder text

Clearing a selection

Search selects support multiple ways to clear the current value:

  • Click the X (clear) button that appears when a value is selected
  • Manually delete the text in the search input
  • Press Backspace on an empty search input

When to use SearchSelect vs Select: Use search select when you have more than 8-10 options or when users will benefit from typing to filter. For short lists, a standard select is simpler.


SearchSelectApollo

A searchable single-select that queries your GraphQL API via Apollo Client. Ideal for searching large datasets server-side.

import { gql } from '@apollo/client'

const SEARCH_USERS = gql`
  query SearchUsers($search: String!) {
    users(where: { name: { contains: $search } }) {
      id
      name
      email
    }
  }
`

FormFieldClass.searchSelectApollo('userId', {
  label: 'Select User',
  required: true,
  placeholder: 'Search users...',
  document: SEARCH_USERS,
  dataType: 'users',
  searchFields: ['name', 'email'],
  selectOptionsFunction: (users) =>
    users.map((user) => ({
      value: user.id,
      label: `${user.name} (${user.email})`,
    })),
})

SearchSelectApollo-specific options

OptionTypeDefaultDescription
documentDocumentNodeGraphQL query document
dataTypestringKey in the query result containing the data array
searchFieldsstring[]Fields to include in the search query
selectOptionsFunction(data) => SelectOption[]Maps query results to select options
placeholderstring'Search...'Placeholder text

How it works

  1. User types in the search input
  2. After a 500ms debounce, a GraphQL query is sent with the search string
  3. Results are mapped through selectOptionsFunction to create dropdown options
  4. When the user selects an option, the value is stored
  5. Clearing the selection triggers a data refetch

ApolloSearchProvider required

Wrap your app with <ApolloSearchProvider> from @nestledjs/forms/apollo, placed inside your existing <ApolloProvider>. Apollo search fields throw a setup error at render time if the provider is missing. Both Apollo Client v3 and v4 are supported, and search selects can also run on a non-Apollo data layer — see Apollo integration for setup and custom adapters.

These fields also work on React Native via @nestledjs/forms-native, using <ApolloSearchProvider> from @nestledjs/forms-native/apollo — including server-side search.


SearchSelectMulti

A searchable multi-select dropdown. Users can type to filter and select multiple options.

FormFieldClass.searchSelectMulti('tags', {
  label: 'Tags',
  placeholder: 'Search tags...',
  options: [
    { value: 'frontend', label: 'Frontend' },
    { value: 'backend', label: 'Backend' },
    { value: 'design', label: 'Design' },
    { value: 'devops', label: 'DevOps' },
    { value: 'mobile', label: 'Mobile' },
    { value: 'security', label: 'Security' },
  ],
})

SearchSelectMulti-specific options

OptionTypeDefaultDescription
optionsSelectOption[][]Array of { value, label } objects
placeholderstring'Search...'Placeholder text

The value returned on submit is an array of selected values: ['frontend', 'backend'].


SearchSelectMultiApollo

A searchable multi-select that queries your GraphQL API via Apollo Client.

const SEARCH_CATEGORIES = gql`
  query SearchCategories($search: String!) {
    categories(where: { name: { contains: $search } }) {
      id
      name
    }
  }
`

FormFieldClass.searchSelectMultiApollo('categoryIds', {
  label: 'Categories',
  placeholder: 'Search categories...',
  document: SEARCH_CATEGORIES,
  dataType: 'categories',
  searchFields: ['name'],
  selectOptionsFunction: (categories) =>
    categories.map((cat) => ({
      value: cat.id,
      label: cat.name,
    })),
})

SearchSelectMultiApollo-specific options

Same as SearchSelectApollodocument, dataType, searchFields, selectOptionsFunction, and placeholder.


Common patterns

User picker with avatar-style labels

FormFieldClass.searchSelectApollo('reviewerId', {
  label: 'Reviewer',
  document: SEARCH_TEAM_MEMBERS,
  dataType: 'teamMembers',
  searchFields: ['name', 'email'],
  selectOptionsFunction: (members) =>
    members.map((m) => ({
      value: m.id,
      label: `${m.name}${m.role}`,
    })),
})

Conditional search field

FormFieldClass.searchSelectApollo('managerId', {
  label: 'Manager',
  document: SEARCH_MANAGERS,
  dataType: 'users',
  searchFields: ['name'],
  selectOptionsFunction: (users) =>
    users.map((u) => ({ value: u.id, label: u.name })),
  showWhen: (values) => values.role !== 'admin',
  requiredWhen: (values) => values.role === 'employee',
})

Use defaultValue with the value string to pre-select an option:

FormFieldClass.searchSelect('category', {
  label: 'Category',
  defaultValue: 'tech',
  options: categoryOptions,
})

For Apollo variants, set defaultValue to the ID and the field will display the matching option when the query loads.

Previous
Selection fields