> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pocketbase/pocketbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Select field

> Store single or multiple values from a predefined list

The select field stores one or more string values from a predefined list of options. It supports both single-select and multi-select modes, with special setter modifiers for manipulating selections.

## Configuration options

<ParamField path="values" type="[]string" required>
  List of accepted values. This defines all possible options that can be selected.
</ParamField>

<ParamField path="maxSelect" type="int" default="1">
  Maximum number of values that can be selected. Set to 1 (or less) for single-select mode. Set to > 1 for multi-select mode.
</ParamField>

<ParamField path="required" type="bool" default="false">
  When true, requires at least one value to be selected.
</ParamField>

## Validation rules

The select field validates:

* **Values**: All selected values must be in the predefined `values` list
* **Max select**: Number of selected values cannot exceed `maxSelect`
* **Required**: If enabled, at least one value must be selected

## Single vs multi-select

<Info>
  The field behavior changes based on `maxSelect`:

  * `maxSelect <= 1`: Single-select mode (value is a string)
  * `maxSelect > 1`: Multi-select mode (value is a string array)
</Info>

## Special setter modifiers

The select field supports several modifiers for manipulating selections:

<CodeGroup>
  ```go Append values theme={null}
  // Add values to the end of the selection
  record.Set("roles+", []string{"editor", "viewer"})
  // Before: ["admin", "moderator"]
  // After:  ["admin", "moderator", "editor", "viewer"]
  ```

  ```go Prepend values theme={null}
  // Add values to the beginning of the selection
  record.Set("+roles", []string{"owner", "admin"})
  // Before: ["moderator", "viewer"]
  // After:  ["owner", "admin", "moderator", "viewer"]
  ```

  ```go Remove values theme={null}
  // Remove specific values from the selection
  record.Set("roles-", "moderator")
  // Before: ["admin", "moderator", "viewer"]
  // After:  ["admin", "viewer"]
  ```
</CodeGroup>

## Go examples

<Tabs>
  <Tab title="Single select">
    ```go theme={null}
    import "github.com/pocketbase/pocketbase/core"

    field := &core.SelectField{
        Name:      "status",
        Required:  true,
        MaxSelect: 1,
        Values:    []string{"draft", "published", "archived"},
    }

    collection.Fields.Add(field)

    // Set single value
    record.Set("status", "published")
    ```
  </Tab>

  <Tab title="Multi select">
    ```go theme={null}
    field := &core.SelectField{
        Name:      "tags",
        Required:  false,
        MaxSelect: 5,
        Values:    []string{"tech", "business", "science", "arts", "sports"},
    }

    collection.Fields.Add(field)

    // Set multiple values
    record.Set("tags", []string{"tech", "business"})
    ```
  </Tab>

  <Tab title="With modifiers">
    ```go theme={null}
    field := &core.SelectField{
        Name:      "permissions",
        MaxSelect: 10,
        Values: []string{
            "read", "write", "delete",
            "admin", "moderator", "editor",
        },
    }

    collection.Fields.Add(field)

    // Set initial values
    record.Set("permissions", []string{"read"})

    // Add more permissions
    record.Set("permissions+", []string{"write", "delete"})

    // Remove a permission
    record.Set("permissions-", "delete")
    // Result: ["read", "write"]
    ```
  </Tab>

  <Tab title="Priority/category">
    ```go theme={null}
    field := &core.SelectField{
        Name:      "priority",
        Required:  true,
        MaxSelect: 1,
        Values:    []string{"low", "medium", "high", "critical"},
    }

    collection.Fields.Add(field)

    record.Set("priority", "high")
    ```
  </Tab>
</Tabs>

## Database column type

The column type varies based on whether it's single or multi-select:

<CodeGroup>
  ```sql Single select (maxSelect <= 1) theme={null}
  TEXT DEFAULT '' NOT NULL
  ```

  ```sql Multi select (maxSelect > 1) theme={null}
  JSON DEFAULT '[]' NOT NULL
  ```
</CodeGroup>

## Common use cases

<CodeGroup>
  ```go Status field theme={null}
  field := &core.SelectField{
      Name:      "status",
      Required:  true,
      MaxSelect: 1,
      Values:    []string{"pending", "approved", "rejected"},
  }
  ```

  ```go User roles theme={null}
  field := &core.SelectField{
      Name:      "roles",
      Required:  true,
      MaxSelect: 3,
      Values:    []string{"user", "admin", "moderator", "editor"},
  }
  ```

  ```go Content categories theme={null}
  field := &core.SelectField{
      Name:      "categories",
      MaxSelect: 5,
      Values: []string{
          "technology", "business", "health",
          "entertainment", "sports", "politics",
      },
  }
  ```

  ```go Size options theme={null}
  field := &core.SelectField{
      Name:      "size",
      Required:  true,
      MaxSelect: 1,
      Values:    []string{"XS", "S", "M", "L", "XL", "XXL"},
  }
  ```
</CodeGroup>

## Querying select fields

<CodeGroup>
  ```go Single select query theme={null}
  // Find records with specific status
  records, err := app.FindRecordsByFilter(
      "articles",
      "status = 'published'",
      "-created",
      10,
      0,
  )
  ```

  ```go Multi select query theme={null}
  // Find records containing a specific tag
  records, err := app.FindRecordsByFilter(
      "articles",
      "tags ?~ 'tech'", // Array contains operator
      "-created",
      10,
      0,
  )
  ```
</CodeGroup>

## Best practices

<Note>
  * Keep the `values` list concise and meaningful
  * Use single-select for mutually exclusive options (status, priority, etc.)
  * Use multi-select for non-exclusive categorization (tags, permissions, etc.)
  * Consider the UX implications of large `values` lists (use relation fields for large datasets)
  * Use `+` and `-` modifiers in multi-select mode for cleaner code
  * Selections are stored in order, duplicates are automatically removed
</Note>

## Zero value

* **Single-select**: Empty string `""`
* **Multi-select**: Empty array `[]`
