Using the Checkboxes Element for Multiple Selectionsfor Drupal 11 , 10 , 9 , and 8

Last updated :  

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 checkboxes definition and its shared #options syntax 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.

Don't assume an empty array means "nothing selected": because every option key is always present in the submitted value (checked or not), $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 to 0. Run it through array_filter() to get the genuinely empty array you might be expecting.)

Key takeaways

  • checkboxes shares #options syntax with select, 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_value for 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.