Format long lists of radio/checkbox options into multiple columns

Public

With lengthy option lists for checkbox and radio fields, it can become necessary to format them so that they fall into multiple columns. While this can be done with css alone, that would pretty much mean floating items left, so that the order of items is left to right, then top to bottom.. But what if the requirement is that options be ordered top to bottom then left to right? For example:
A D G
B E H
C F I

Rather than,
A B C
D E F
G H I

This snippet will allow that, simply by adding a '#columns' parameter with the desired number of columns to split items into, and telling the form element to this custom theme function.

Get raw version
php
  1. /**
  2.  * Implements hook_theme().
  3.  */
  4. function MYMODULE_video_gallery_theme() {
  5. return array(
  6. 'multicolumn_options' => array(
  7. 'render element' => 'form',
  8. ),
  9. );
  10. }
  11.  
  12. /**
  13.  * Theme function to format elements into multiple columns
  14.  */
  15. function theme_multicolumn_options($element) {
  16. $stripped_element = array_values($element);
  17. $element = $stripped_element[0];
  18.  
  19. // Initialize variables.
  20. $output = '';
  21. $total_columns = (isset($element['#columns'])) ? $element['#columns'] : 2;
  22. $total_options = count($element['#options']);
  23. $options_per_column = ceil($total_options / $total_columns);
  24. $keys = array_keys($element['#options']);
  25. $type = $element[$keys[0]]['#type'];
  26.  
  27. // Start wrapper div.
  28. $output .= '<div class="multicolumn-options-wrapper clearfix">';
  29. $current_column = 1;
  30. $current_option = 0;
  31.  
  32. while ($current_column <= $total_columns) {
  33. // Start column div.
  34. $output .= '<div class="multicolumn-options-column">';
  35.  
  36. // Keep looping through until the maximum options per column are reached,
  37. // or you run out of options.
  38. while ($current_option < $options_per_column * $current_column
  39. && $current_option < $total_options) {
  40.  
  41. // Output as either check or radio button depending on the element type.
  42. $output .= drupal_render($element[$keys[$current_option]]);
  43. $current_option++;
  44. }
  45.  
  46. // End column div.
  47. $output .= '</div>';
  48. $current_column++;
  49. }
  50.  
  51. // End wrapper div.
  52. $output .= '</div>';
  53.  
  54. return $output;
  55. }
  56.  
  57. /**
  58.  * USAGE:
  59.  * Add #columns parameter to form element, and set it to use our theme function...
  60.  *
  61.  *
  62.  * $form['list'] = array(
  63.  * '#type' => 'radios',
  64.  * '#options' => $list_options,
  65.  * '#default_value' => $active_option,
  66.  * '#theme' => array('multicolumn_options'),
  67.  * '#columns' => 4,
  68.  * );
  69.  */

Comments

Steve's picture

Absolute legend, thanks :)