1

I've created a custom table using a tableselect element, and within each row, I have a checkbox form element that should populate the checkbox from a checkbox field in the node. I've tried every possible format of #default_value (setting it to 1, array(1), etc), to no avail. Since in HTML it's the checked attribute that causes a checkbox to show as checked, I came up with this option:

  foreach($translations as $locale => $locale_data) {
    // Get data for other fields...

    // Get data for Staging Only checkbox
    $staging_only = isset($entity->field_pub_staging_only[$locale]) ? (int)$entity->field_pub_staging_only[$locale][0]['value'] : 0;

    $row = array(
     'language_locale' => $locale_link,
     'status' => $status,
     'stage_url' => $stage_url,
     'start_date' => array(
       'data'=> array(
         '#type'=>'textfield',
         '#value'=> $new_start_date,
         '#title' => 'Start Date',
         '#title_display'=>'invisible',
         '#name'=> 'start_date[' . $locale . ']',
         '#id'=>  'start-date[' . $locale . ']',
         '#attributes' => array('class' => array('datepicker')),
         '#size' => 10,
         '#maxlength' => 10
       ),
     ),
     'end_date' => array(
       'data'=> array(
         '#type'=>'textfield',
         '#value'=> $new_end_date,
         '#title' => 'End Date',
         '#title_display'=>'invisible',
         '#name'=> 'end_date[' . $locale . ']',
         '#id'=> 'end-date[' . $locale . ']',
         '#attributes' => array('class' => array('datepicker')),
         '#size' => 10,
         '#maxlength' => 10
       ),
     ),
      'staging_only' => array(
        'data'=> array(
          '#type'=>'checkbox',
          '#title' => 'Staging Only',
          '#title_display'=>'invisible',
          '#name'=> 'staging_only[' . $locale . ']',
          '#id'=> 'staging_only[' . $locale . ']',
          '#default_value' => $staging_only
        ),
      ),
      'display_title' => $title
    );

    if ($staging_only) {
      $row['staging_only']['data']['#attributes'] = array('checked' => array('checked'));
    }

    $options[$locale] = $row;
  }

  $header = array(
    'language_locale' => t('Language Locale'),
    'status' => t('Status'),
    'stage_url' => t('Stage URL'),
    'start_date' => t('Start Date'),
    'end_date' => t('End Date'),
    'staging_only' => t('Staging Only'),
    'display_title' => t('Display Title')
  );

  $form['table'] = array(
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options,
    '#empty' => t('No content available.'),
    '#attributes' => array('id' => array('locale-table')),
  );

...

  $form['submit'] = array(
    '#type'=>'submit',
    '#value' => 'Submit',
  );

  return $form;
}

where I'm basically manually added the checked attribute to the element when it's checked. It works, but it seems sort of hackish, since it's not using what would normally be used to set a form element value with Form API. Is there a better way to do this with the usual Form API settings?

CLARIFICATION It appears that my question wasn't clear, based on the answers I've received so far. The issue is not whether the tableselect row checkbox is checked by default; the issue is attempting to mark as checked the staging_only checkbox, which is a separate from api element within the tableselect row.

2 Answers 2

1

I remember struggling with this for a moment ! The documentation is not so explicit..

The tableselect element takes a #default_value array as a multiple select element would do, that is at the same level as the #options array, and with each selected option key being mapped to a truthy value, usually integer 1.

In the foreach, you would do something like this :

if ($staging_only) {
  // $row['staging_only']['data']['#attributes'] = array('checked' => array('checked'));
  $selection[$locale] = 1;
}

And then :

$form['table'] = array(
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $options,
  '#default_value' => $selection,
  '#empty' => t('No content available.'),
  '#attributes' => array('id' => array('locale-table'))
);

Non present options in the selection array default to false so you can ignore unchecked values.

0

Use the #default_value key of the form. This key will reference an array of the same shape as the values in $form_state, which will have only the rows checked. Each item will have a key the same as its value, these keys/values will be the key of each row in the table. Sounds complicated but it is not. Check these two examples.

Rows with sequential key

$rows =  [
  [ 1, 'first value'], // row 0
  [ 2, 'first value'], // row 1
];

// will select the first row
$selection = [0 => 0];

$form['table'] = [
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $rows,
  '#default_value' => $selection,
  '#empty' => t('No content available.'),
  '#attributes' => ['id' => ['locale-table']]
];

Rows as an associative array

$rows =  [
  'r11' => [ 123, 'first value'], // row 0
  'k22' => [ 243, 'first value'], // row 1
];

// will select the first row and the second row
$selection = [
  'r11' => 'r11',
  'k22' => 'k22',
];

Your Answer

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

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