5

I have a custom form that displays a form element of about 2 dozen checkboxes. I would like to output them 3 per row, in a table if possible. How can I go about doing that?

$form['preference'] = array(
    '#type' => 'checkboxes',
      '#default_value' => 1373,
    '#required' => TRUE,
    '#title' => 'Choose all that apply',
    '#options' => $preference_options,
    '#prefix' => '<div id="preference-options">',
    '#suffix' => '</div>',
  );
2
  • Not sure what it is that you're asking. What you've done seems correct. Are you talking about how you style them so that each group sits on it's own line? If so this is more of a CSS question and not a Drupal one.
    – Camsoft
    Commented Mar 5, 2011 at 19:02
  • Drupal is outputting a div with a label and input inside of it. It would make more sense to have a table for a grid because the CSS can be tricky.
    – Kevin
    Commented Mar 5, 2011 at 19:15

2 Answers 2

8

First, define a custom theme function with hook_theme() and assign it to the form element with #theme.

In that theme function, you can use expand_checkboxes to convert it into an array of separate checkbox elements. Then, re-structure it into an array with 3 elements each, render the checkboxes and pass it to theme_table().

Something like this, all untested.

function theme_yourmodule_preference($element) {
  $elements = element_children(expand_checkboxes($element));

  $rows = array();
  for ($i = 0; $i < count($elements); $i += 3) {
    $row = array(drupal_render($elements[$i]));
    // The following two might not always exist, check first.
    if (isset($elements[$i + 1]) {
      $row[] = drupal_render($elements[$i + 1]);
    }
    if (isset($elements[$i + 2]) {
      $row[] = drupal_render($elements[$i + 2]);
    }
    $rows[] = $row;
  }
  return theme('table', array(), $rows);
}
1
  • I needed to use return theme('table', array('rows' =>$rows)); - are you sure your code is OK?
    – Mołot
    Commented Jun 3, 2014 at 6:28
4

I adapted Berdir's solution for display in columns and Drupal 7. Thought I'd share it.

function yourmodule_theme() {
  return array
      (
      'form_yourmodule_form' => array
          (
          'render element' => 'form'
      ),
  );
}

function theme_form_yourmodule_form($variables) {

  $form = $variables['form'];

  $element = $form['checkboxelement'];
  unset($form['checkboxelement']);

  $elements = element_children(form_process_checkboxes($element));

  $colnr = 3;   // set nr of columns here

  $itemCount = count($elements);
  $rowCount = $itemCount / $colnr;
  if (!is_int($rowCount))
    $rowCount = round((($itemCount / $colnr) + 0.5), 0, PHP_ROUND_HALF_UP);
  $rows = array();
  for ($i = 0; $i < $rowCount; $i++) {
    $row = array();
    for ($col = 0; $col < $colnr; $col++) {
      if (isset($elements[$i + $rowCount * $col]))
        $row[] = drupal_render($element[$elements[$i + $rowCount * $col]]);
    }
    $rows[] = $row;
  }

  $variable = array(
      'header' => array(),
      'rows' => $rows,
      'attributes' => array('class' => 'checkbox_columns'),
      'caption' => NULL,
      'colgroups' => NULL,
      'sticky' => NULL,
      'empty' => NULL,
  );


  $output = theme_table($variable);

  $output .= drupal_render_children($form);

  return $output;
}

I found an even easier solution: there is a module for this! Multi-column checkboxes radios

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.