Last updated October 2, 2011. Created by webchick on December 30, 2010.
Edited by JuliaKM, mwsam. Log in to edit this page.
This snippet allows you to format your checkboxes/radio buttons into multiple columns.
Add the following to hook_theme():
<?php
function mymodule_theme() {
return array(
...
# New!
'multicolumn_options' => array(
'arguments' => array('element' => NULL),
),
...
);
}
?>And the following somewhere in your .module file:
<?php
/**
* Output a list of options in the number of columns specified by the element's
* #columns value.
*/
function theme_multicolumn_options($element) {
// Initialize variables.
$output = '';
$total_columns = $element['#columns'];
$total_options = count($element['#options']);
$options_per_column = ceil($total_options / $total_columns);
$keys = array_keys($element['#options']);
$type = $element[$keys[0]]['#type'];
// Start wrapper div.
$output .= '<div class="multicolumn-options-wrapper">';
$current_column = 1;
$current_option = 0;
while ($current_column <= $total_columns) {
// Start column div.
$output .= '<div class="multicolumn-options-column" style="width: ' . 100 / $total_columns . '%; float: left">';
// Keep looping through until the maximum options per column are reached,
// or you run out of options.
while ($current_option < $options_per_column * $current_column &&
$current_option < $total_options) {
// Output as either check or radio button depending on the element type.
$output .= theme($type, $element[$keys[$current_option]]);
$current_option++;
}
// End column div.
$output .= '</div>';
$current_column++;
}
// End wrapper div.
$output .= '</div>';
$output .= '<div class="clear-block"></div>';
return $output;
}
?>Now, on any form checkboxes or radios element where you want to format the options into multiple columns, add a #theme and #columns property.
Change:
<?php
$element['example'] = array(
'#type' => 'checkboxes',
'#title' => t('Example checkboxes'),
'#options' => $options,
);
?>To:
<?php
$element['example'] = array(
'#type' => 'checkboxes',
'#title' => t('Example checkboxes'),
'#options' => $options,
# New!
'#theme' => array('multicolumn_options'),
'#columns' => 2,
);
?>This will format the options for the "example" checkbox into two columns instead of one long column.
Please note that the Multi-column checkboxes radios project is a nice alternative for a more fully-featured and cross-module compatible version of this. (Except it uses tables. Ick! ;))
Comments
Newbie questions
Is this snippet compatible with the Webform module? (I'm using Webform 6.x-2.10.) If so, where would I add the various snippets?
I've tried the "Multi-column checkboxes radios" as per http://drupal.org/node/603900 and it worked perfectly - BUT I couldn't find a way to make it only apply to some forms and not others. Many forms on my site depend on the default behavior (non-multi-column) so I only want multi-column to affect certain forms. Is this possible with this snippet? Thanks!
Hot!
I love it when a quick Google search saves me an hour of writing my own code!
Thanks!
awesome! i could have figured
awesome! i could have figured this out on my own, but you just saved me an hour :-) thanks, webchick!
Drupal 7 version
I got this working on my D7 site, with a bit of struggle. Here are the changes that I had to make to get it working:
function theme_multicolumn_options($element)to have these 3 new lines at the beginning:function theme_multicolumn_options($element) {// Modify to dig one layer deeper. Not sure why original code didn't need this.
$stripped_element = array_values($element);
$element = $stripped_element[0];
...
theme_multicolumn_options()function, comment out the theme() invocation, and replace with drupal_render():// $output .= theme($type, $element[$keys[$current_option]]);$output .= drupal_render($element[$keys[$current_option]]);
Without this, it was displaying only the checkboxes without their text beside them.
With these changes, it's working great for me!
Oh, and BTW, I'm using it with the Profile2 module, for a termreference fieldtype (lists a bunch of terms from a taxonomy for you to associate with your user account) in the "main" profile. Here is how I invoked the multicolumns, with hook_form_alter:
/*** Implementation of hook_form_alter()
*/
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_register_form' || $form_id == 'user_profile_form' && $form['#user_category'] == 'main') {
$form['profile_main']['field_specialties']['und']['#theme'] = array('multicolumn_options');
$form['profile_main']['field_specialties']['und']['#multicolumn_numcols'] = 4;
}
}
Ah, yes, that was one other change I made. I noticed that "#columns" was already in use, I think by profile2, so I renamed it to "#multicolumn_numcols". A corresponding change in theme_multicolumn_options() was to change the $total_columns line to:
$total_columns = $element['#multicolumn_numcols'];So in the end, that function looked like this:
function theme_multicolumn_options($element) {
// Modify to dig one layer deeper. Not sure why original code didn't need this.
$stripped_element = array_values($element);
$element = $stripped_element[0];
// Initialize variables.
$output = '';
$total_columns = $element['#multicolumn_numcols'];
$total_options = count($element['#options']);
$options_per_column = ceil($total_options / $total_columns);
$keys = array_keys($element['#options']);
$type = $element[$keys[0]]['#type'];
// Start wrapper div.
$output .= '<div class="multicolumn-options-wrapper">';
$current_column = 1;
$current_option = 0;
while ($current_column <= $total_columns) {
// Start column div.
$output .= '<div class="multicolumn-options-column" style="width: ' . 100 / $total_columns . '%; float: left">';
// Keep looping through until the maximum options per column are reached,
// or you run out of options.
while ($current_option < $options_per_column * $current_column &&
$current_option < $total_options) {
// Output as either check or radio button depending on the element type.
$output .= drupal_render($element[$keys[$current_option]]);
// $output .= theme($type, $element[$keys[$current_option]]);
$current_option++;
}
// End column div.
$output .= '</div>';
$current_column++;
}
// End wrapper div.
$output .= '</div>';
$output .= '<div class="clear-block"></div>';
return $output;
}
Can you submit a patch for
Can you submit a patch for this to the maintainer?
In addition
For Drupal 7, the hook_theme() function is slightly different (from Drupal 6 version) as well ...
see http://www.jaypan.com/blog/themeing-drupal-7-forms-including-css-and-js
For a form, we need to specify 'render element' instead of 'variables' (and to have the 'form' as value).
/*** Implements hook_theme().
*/
function MY_MODULE_theme() {
return array(
'multicolumn_options' => array(
'render element' => 'form',
),
);
}
thanks spouilly, some
thanks spouilly, some variables in the theme function have to be changed then too
// $stripped_element = array_values($element);
//$element = $stripped_element[0];
$element = $element["form"];
and type has to be
//$type = $element[$keys[0]]['#type'];
$type = $element['#type'];
A little from each for Drupal 7
In Drupal 7 the following worked for me...
Leave alterations to element as dan3h has it
$stripped_element = array_values($element);$element = $stripped_element[0];
Use theme() as the original
$output .= theme($type, $element[$keys[$current_option]]);//$output .= drupal_render($element[$keys[$current_option]]);
And be sure your variable for columns matches what you have...
// $total_columns = $element['#multicolumn_numcols'];$total_columns = $element['#columns'];
_____________________
Daniel Schiavone
www.SnakeHill.net
Some trick to work with D7.22
Thanks to all for sharing. Here is my trick for my site.
function mymodule_theme() {
return array(
'multicolumn_options' => array(
'render element' => 'element', // If use agruments=>'element', It will throw notice: indefined index render element in theme()....
),
);
};
in theme_multicolumn_options(), I used $output .= drupal_render($element[$keys[$current_option]]); instead of $output .= theme(....).
Best Regards.