Multi-select Fields

Multi-select fields give you an input where multiple items may be selected.

Screenshot of the multi-select field interface in the Craft control panel

# Settings

my-craft-project.ddev.site/admin/settings/fields/new
Dropdown field settings screen in the Craft control panel
Adding a new multi-select field via the control panel.

Multi-select fields have the following settings:

  • Multi-select Options – Define any number of options to populate the menu.
    • Optgroup? — Converts this option into a non-selectable “heading” to group other options.
    • Label — A text description of the option, displayed to the author.
    • Value — The value stored when a given option is selected.
    • Icon (Optional) — Choose from the standard system icon palette.
    • Color (Optional) — A color for the icon, or, when no icon is selected, a color pip.
    • Default? — One option can be marked as the default.

# Development

The order in which options are selected is not preserved, and . If you wish to order the selections, consider using one of the relational fields.

# Working with Multi-select Field Data

If you have an element with a multi-select field in your template, you can access its data using your multi-select field’s handle:

{% set value = entry.myFieldHandle %}

That will give you a craft\fields\data\MultiOptionsFieldData (opens new window) object that contains the selected options’ labels and values. You can use this like an array:

{% for option in entry.myFieldHandle %}
  Label: {{ option.label }}
  Value: {{ option }} or {{ option.value }}
{% endfor %}

To loop through all the available options, iterate over the options (opens new window) property:

{% for option in entry.myFieldHandle.options %}
  Label:    {{ option.label }}
  Value:    {{ option }} or {{ option.value }}
  Selected: {{ option.selected ? 'Yes' : 'No' }}
{% endfor %}

To see if any options are selected, use the length (opens new window) filter (or PHP’s count() function):

{% if entry.myFieldHandle|length %}
  {# At least one option was selected! #}
{% endif %}

To see if a particular option is selected, use contains() (opens new window):

{% if entry.myFieldHandle.contains('foo') %}
  {# `foo` is among the selected options! #}
{% endif %}

# Querying Elements with Multi-select Fields

When querying for elements that have a Multi-select field, you can filter the results based on the multi-select field data using a query param named after your field’s handle.

Possible values include:

Value Fetches elements…
'foo' with a foo option selected.
'not foo' without a foo option selected.
['foo', 'bar'] with foo or bar options selected.
['and', 'foo', 'bar'] with foo and bar options selected.
{# Fetch entries with the 'foo' option selected #}
{% set entries = craft.entries()
  .myFieldHandle('foo')
  .all() %}

# Saving Multi-select Fields

If you have a front-end element form (such as an entry form (opens new window)) that incorporates multi-select field data, you can use this template as a starting point:

{# Fetch the global field definition: #}
{% set field = craft.app.fields.getFieldByHandle('myFieldHandle') %}

{# Include a hidden input first so Craft knows to update the
   existing value, if no options are selected + submitted. #}
{{ hiddenInput('fields[myFieldHandle]', '') }}

<select multiple name="fields[myFieldHandle][]">
  {% for option in field.options %}
    {% set selected = entry is defined
      ? entry.myFieldHandle.contains(option.value)
      : option.default %}

    {{ tag('option', {
      value: option.value,
      text: option.label,
      selected: selected,
    })}}
  {% endfor %}
</select>