| 1 |
<?php
|
| 2 |
// $Id: betterselect.module,v 1.7 2008/09/08 01:02:12 setvik Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Use stylized checkboxes instead of the default multiple select HTML element.
|
| 7 |
*
|
| 8 |
* @todo: Fix bug with required elements; values don't seem to "take".
|
| 9 |
*/
|
| 10 |
|
| 11 |
/**
|
| 12 |
* Implementation of hook_menu().
|
| 13 |
*/
|
| 14 |
function betterselect_menu() {
|
| 15 |
$items = array();
|
| 16 |
$items['admin/settings/betterselect'] = array(
|
| 17 |
'title' => t('Better Select'),
|
| 18 |
'description' => t('Configure better select settings.'),
|
| 19 |
'page callback' => 'drupal_get_form',
|
| 20 |
'page arguments' => array('betterselect_admin_settings'),
|
| 21 |
'access arguments' => array('administer site configuration'),
|
| 22 |
'type' => MENU_NORMAL_ITEM,
|
| 23 |
);
|
| 24 |
return $items;
|
| 25 |
}
|
| 26 |
|
| 27 |
/**
|
| 28 |
* Build settings form().
|
| 29 |
*/
|
| 30 |
function betterselect_admin_settings() {
|
| 31 |
$form['betterselect_scroll'] = array(
|
| 32 |
'#type' => 'checkbox',
|
| 33 |
'#title' => t('Place options in a scrollable div'),
|
| 34 |
'#default_value' => variable_get('betterselect_scroll', FALSE),
|
| 35 |
);
|
| 36 |
|
| 37 |
$form['betterselect_node_form_only'] = array(
|
| 38 |
'#type' => 'checkbox',
|
| 39 |
'#title' => t('Only convert select lists on node forms'),
|
| 40 |
'#default_value' => variable_get('betterselect_node_form_only', FALSE),
|
| 41 |
);
|
| 42 |
|
| 43 |
return system_settings_form($form);
|
| 44 |
}
|
| 45 |
|
| 46 |
/**
|
| 47 |
* Implementation of hook_elements().
|
| 48 |
*/
|
| 49 |
function betterselect_elements() {
|
| 50 |
$type = array();
|
| 51 |
$type['select']['#process'] = array('betterselect_process');
|
| 52 |
|
| 53 |
return $type;
|
| 54 |
}
|
| 55 |
|
| 56 |
/**
|
| 57 |
* Form process callback; translates multiselect fields into checkboxes.
|
| 58 |
*/
|
| 59 |
function betterselect_process($element, $edit, $form_state, $complete_form) {
|
| 60 |
if (isset($element['#multiple']) && $element['#multiple'] == TRUE && !(variable_get('betterselect_node_form_only', FALSE) == TRUE && $complete_form['#id'] != 'node-form')) {
|
| 61 |
|
| 62 |
// If we're dealing with taxonomy, fix the option titles.
|
| 63 |
if (is_object($element['#options'][0])) {
|
| 64 |
// Build new array of options in format that theme_checkboxes expects.
|
| 65 |
$options = array();
|
| 66 |
$defaults = array();
|
| 67 |
foreach ($element['#options'] as $option) {
|
| 68 |
if (is_array($option->option)) {
|
| 69 |
foreach ($option->option as $tid => $name) {
|
| 70 |
$options[$tid] = check_plain($name);
|
| 71 |
}
|
| 72 |
}
|
| 73 |
}
|
| 74 |
$element['#options'] = $options;
|
| 75 |
}
|
| 76 |
|
| 77 |
|
| 78 |
// The default value should be an array, if it isn't expand_checkboxes()
|
| 79 |
// will make it one.
|
| 80 |
if (isset($element['#default_value']) && is_array($element['#default_value']) && count($element['#default_value'])) {
|
| 81 |
// Fix the value arrays; checkboxes are the exact inverse of multiselect,
|
| 82 |
// apparently for vindictive fun.
|
| 83 |
|
| 84 |
// First make sure there's at least 1 non-blank array element
|
| 85 |
$temp = $element['#default_value'];
|
| 86 |
$temp = array_shift($element['#default_value']);
|
| 87 |
if (!empty($temp)) {
|
| 88 |
$element['#default_value'] = array_flip($element['#default_value']);
|
| 89 |
$element['#value'] = array_flip($element['#value']);
|
| 90 |
}
|
| 91 |
|
| 92 |
}
|
| 93 |
|
| 94 |
|
| 95 |
// Place options in a scrollable or non-scrollable div
|
| 96 |
$div_class = variable_get('betterselect_scroll', FALSE) ? 'form-checkboxes-scroll' : 'form-checkboxes-noscroll';
|
| 97 |
$element['#attributes'] = array('class' => $div_class);
|
| 98 |
|
| 99 |
// Switch display to checkboxes instead.
|
| 100 |
$element['#type'] = 'checkboxes';
|
| 101 |
unset($element['#theme']);
|
| 102 |
$element = expand_checkboxes($element);
|
| 103 |
|
| 104 |
// Hide the silly "None" option. (assumes array element with a blank key is the "None" option)
|
| 105 |
if (!$element['#required'] && is_array($element[''])) {
|
| 106 |
$element['']['#prefix'] = '<div style="display:none">';
|
| 107 |
$element['']['#suffix'] = '</div>';
|
| 108 |
}
|
| 109 |
|
| 110 |
// Include the JS and CSS files.
|
| 111 |
static $path;
|
| 112 |
if (!isset($path)) {
|
| 113 |
$path = drupal_get_path('module', 'betterselect');
|
| 114 |
drupal_add_css($path . '/betterselect.css');
|
| 115 |
drupal_add_js($path . '/betterselect.js');
|
| 116 |
}
|
| 117 |
|
| 118 |
// Add the necessary prefix/suffix to make JS/CSS work.
|
| 119 |
$size = isset($element['#size']) ? $element['#size'] : 10;
|
| 120 |
$prefix = isset($element['#prefix']) ? $element['#prefix'] : '';
|
| 121 |
$suffix = isset($element['#suffix']) ? $element['#suffix'] : '';
|
| 122 |
$fixheight = count($element['#options']) > $size ? ' betterfixed' : '';
|
| 123 |
$element['#prefix'] = '<div class="better-select' . $fixheight . '">' . $prefix;
|
| 124 |
$element['#suffix'] = $suffix . '</div>';
|
| 125 |
}
|
| 126 |
return $element;
|
| 127 |
}
|
| 128 |
|
| 129 |
/**
|
| 130 |
* Implementation of hook_form_alter().
|
| 131 |
*/
|
| 132 |
function betterselect_form_alter(&$form, $form_state, $form_id) {
|
| 133 |
// Taxonomy stores its #options in a weird way; we need to move it back once we're done.
|
| 134 |
if (($form['#id'] == 'node-form' && isset($form['taxonomy']))) {
|
| 135 |
$form['#submit'][] = 'betterselect_taxonomy_from_checkboxes';
|
| 136 |
}
|
| 137 |
elseif ($form_id == 'taxonomy_form_term') {
|
| 138 |
// betterselect has to process it before taxonomy module
|
| 139 |
array_unshift($form['#submit'], 'betterselect_taxonomy_form_term_from_checkboxes');
|
| 140 |
}
|
| 141 |
}
|
| 142 |
|
| 143 |
function betterselect_taxonomy_form_term_from_checkboxes($form, &$form_state) {
|
| 144 |
$fix = array('parent', 'relations');
|
| 145 |
foreach ($fix as $select) {
|
| 146 |
$options = array();
|
| 147 |
foreach ($form_state['values'][$select] as $tid => $selected) {
|
| 148 |
if ($selected) {
|
| 149 |
$options[$tid] = $tid;
|
| 150 |
}
|
| 151 |
}
|
| 152 |
$form_state['values'][$select] = $options;
|
| 153 |
}
|
| 154 |
}
|
| 155 |
|
| 156 |
/**
|
| 157 |
* Restore submitted checkbox values back to format Taxonomy module expects.
|
| 158 |
*/
|
| 159 |
function betterselect_taxonomy_from_checkboxes($form, &$form_state) {
|
| 160 |
foreach ($form_state['values']['taxonomy'] as $index => $properties) {
|
| 161 |
if (is_numeric($index) && $form['taxonomy'][$index]['#multiple']) {
|
| 162 |
$options = array();
|
| 163 |
foreach ($form_state['values']['taxonomy'][$index] as $tid => $selected) {
|
| 164 |
if ($selected) {
|
| 165 |
$options[$tid] = $tid;
|
| 166 |
}
|
| 167 |
}
|
| 168 |
$form_state['values']['taxonomy'][$index] = $options;
|
| 169 |
}
|
| 170 |
}
|
| 171 |
}
|