Dot All Lisbon – the official Craft CMS conference – is happening September 23 - 25.
Multi-select Fields
Multi-select fields give you an input where multiple items may be selected.
Settings
url="https://my-craft-project.ddev.site/admin/settings/fields/new" :link="false" :max-height="500" caption="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 %}
$value = $entry->myFieldHandle;
That will give you a craft5:craft\fields\data\MultiOptionsFieldData 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 %}
foreach ($entry->myFieldHandle as $option) {
// Label: $option->label
// Value: (string)$option or $option->value
}
To loop through all the available options, iterate over the options property:
{% for option in entry.myFieldHandle.options %}
Label: {{ option.label }}
Value: {{ option }} or {{ option.value }}
Selected: {{ option.selected ? 'Yes' : 'No' }}
{% endfor %}
foreach ($entry->myFieldHandle->options as $option) {
// Label: $option->label
// Value: (string)$option or $option->value
// Selected: $option->selected
}
To see if any options are selected, use the length filter (or PHP’s count()
function):
{% if entry.myFieldHandle|length %}
{# At least one option was selected! #}
{% endif %}
if (count($entry->myFieldHandle)) {
// At least one option was selected!
}
To see if a particular option is selected, use contains():
{% if entry.myFieldHandle.contains('foo') %}
{# `foo` is among the selected options! #}
{% endif %}
if ($entry->myFieldHandle->contains('foo')) {
// `foo` is among the selected options!
}
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() %}
// Fetch entries with the 'foo' option selected
$entries = \craft\elements\Entry::find()
->myFieldHandle('foo')
->all();
Saving Multi-select Fields
If you have a front-end element form (such as an entry form) 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]', '') }}
{% 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 %}