Where the previous lesson's single checkbox handles one yes/no question, checkboxes (plural) handles "pick any number from this list" — interests, tags, permissions to grant. It shares its #options syntax with select, but its submitted value shape is genuinely different, and that difference matters.
What you'll learn in this lesson
- The
checkboxesdefinition and its shared#optionssyntax with select - Exactly what gets submitted for checked versus unchecked options
- Setting multiple pre-checked defaults at once
A basic checkboxes element
$form['interests'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Interests'),
'#options' => [
'sports' => $this->t('Sports'),
'music' => $this->t('Music'),
'tech' => $this->t('Technology'),
],
];
Same #options array shape as select — keys become the stored identifiers, values are the visible, translatable labels.
The submitted value: every key, every time
Here's the detail worth internalizing: like the single checkbox, Drupal's checkboxes element always returns every key from #options in $form_state->getValues() — checked options map to their own key as the value, unchecked ones map to 0.
// If only 'music' was checked:
// $form_state->getValue('interests') === [
// 'sports' => 0,
// 'music' => 'music',
// 'tech' => 0,
// ];
To get just the selected ones as a clean list, filter out the falsy entries:
$selected = array_filter($form_state->getValue('interests'));
// $selected === ['music' => 'music'];
Pre-checking multiple defaults
'#default_value' => ['sports', 'tech'],
#default_value takes a plain array of the keys that should start checked — unlike the values shape described above, this one is just a simple array of strings, not the checked/0 keyed structure you get back on submission.
$form_state->getValue('interests') is never empty even when the user selected nothing — it's an array full of 0s. Always run it through array_filter() before checking whether the user actually chose anything.Quick check: a checkboxes element has 5 options, and a user checks none of them. Is
$form_state->getValue('field_name')an empty array? (No — it's an array with 5 entries, each set to0. Run it througharray_filter()to get the genuinely empty array you might be expecting.)
Key takeaways
checkboxesshares#optionssyntax withselect, but the submitted value shape is different — every key is always present, checked or not.- Use
array_filter()to reduce the submitted value down to just the selected keys. #default_valuefor pre-checking takes a plain array of keys — a different shape from what comes back on submission.
Coming up next
Checkboxes let a user pick many. The next lesson covers radios — visually similar, but constrained to exactly one choice from the set.