I'm working on a migration project. I have a form in a custom module that creates a series of checkboxes for URLs to scrape. The form logic looks like this:

foreach ( \Drupal\scrape\Api\Scraper::loadUrls() as $index => $url ) {
  $form['url_' . $index] = [
    '#type' => 'checkbox',
    '#title' => $url . ' — ' . \Drupal::l('(link)', Url::fromUri($url)),
    '#return_value' => $url,

This code does what I want it to do, but all the checkboxes default to 'unchecked'.

'url_0' => integer0
'url_1' => string(27) "https://myurl1.com"
'url_2' => integer0

I want these checkboxes to default to checked. I couldn't find documentation on how to do it in Drupal 8, so I tried several things, and finally hit upon '#checked' => TRUE, (or any value that evaluates truthily). Now the checkboxes are defaulting to checked.

However, even though I have #return_value specified, the value returned in the form submission is now TRUE (from kint):

'url_0' => boolTRUE
'url_1' => boolTRUE
'url_2' => boolTRUE

Since any truthy value defaults the checkbox to checked, I tried '#value' => $url, but then upon submission, the values don't indicate their checked status:

'url_0' => string(86) "https://myurl0.com"
'url_1' => string(27) "https://myurl1.com"
'url_2' => string(29) "https://myurl2.com"

I guess my final option is to have a separate, hidden value for each URL, and map checkbox values to see if the user wants that URL included.

Is there a way I can default my checkboxes to TRUE, while maintaining their #return_value?

3 Answers 3


Sorry for such a late response but it is possible, I ran into this same issue using 8.5.3 the below configuration worked for me. You just have to use both together, i successfully passed numbers, text, bool (becomes 0 or 1), and arrays through #return_value. The class was just for formatting, you can leave that out if you're not using it.

'checkbox_1' => [
    '#type' => 'checkbox',
    '#title' => t('Checkbox 1'),
    '#default_value' => 1,         // Default to checked
    '#return_value' => "checked",  // Return the value if checked
    '#attributes' => ['class'=>['check_group']],
'checkbox_2' => [
    '#type' => 'checkbox',
    '#title' => t('Checkbox 2'),
    '#default_value' => 0,         // Default to unchecked
    '#return_value' => "checked",  // Return the value if checked
    '#attributes' => ['class'=>['check_group']],

Output will look like this if you dpm($form_state->getValues()) in your submit or validate function.

    [checkbox_1] => checked
    [checkbox_2] => 0

You should use the #default_value property. E.g:

 $form['demo'] = [
    '#type' => 'checkbox',
    '#title' => $this->t('Demo'),
    '#default_value' => TRUE,

I guess you can't. I just created hidden fields, and mapped them in the submit.

This is what I basically did:

public function submitForm(array &$form, FormStateInterface $form_state) {

  $values = $form_state->getValues();

  $i = 0;

  while ( TRUE ) {
    if ( ! isset($values['checkboxes'][$i] ) {

That's not verbatim but basically what I did. Simple looping and checking for the checkbox value.

  • can you share sample?
    – dresh
    Commented Dec 11, 2018 at 22:51
  • @dresh see edited question. Not a complicated solution.
    – user1359
    Commented Jan 4, 2019 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.