t('Better select'), 'description' => t('Configure better select settings.'), 'page callback' => 'drupal_get_form', 'page arguments' => array('betterselect_admin_settings'), 'access arguments' => array('administer site configuration'), 'type' => MENU_NORMAL_ITEM, ); return $items; } /** * Build settings form(). */ function betterselect_admin_settings() { $form['betterselect_general'] = array( '#type' => 'fieldset', '#title' => t('General options'), ); $form['betterselect_general']['betterselect_scroll'] = array( '#type' => 'checkbox', '#title' => t('Scrollable div'), '#description' => t('Place options in a scrollable div'), '#default_value' => variable_get('betterselect_scroll', FALSE), ); $form['betterselect_general']['betterselect_node_form_only'] = array( '#type' => 'checkbox', '#title' => t('Node form only'), '#description' => t('Only convert select lists on node forms'), '#default_value' => variable_get('betterselect_node_form_only', FALSE), ); $form['betterselect_taxonomy'] = array( '#type' => 'fieldset', '#title' => t('Taxonomy options'), ); $form['betterselect_taxonomy']['betterselect_save_lineage'] = array( '#type' => 'checkbox', '#title' => t('Save lineage'), '#description' => t('If a user selects a child term when saving a node, automatically save the parent term too.'), '#default_value' => variable_get('betterselect_save_lineage', FALSE), ); $form['betterselect_taxonomy']['betterselect_add_depth_classes'] = array( '#type' => 'checkbox', '#title' => t('Add depth classes'), '#description' => t('Add an extra div to each betterselect option, with a class indicating depth in taxonomy hierarchy. Good for styling parent/child.'), '#default_value' => variable_get('betterselect_add_depth_classes', FALSE), ); return system_settings_form($form); } /** * Implementation of hook_elements(). */ function betterselect_elements() { $type = array(); $type['select']['#process'] = array('betterselect_process'); return $type; } /** * Form process callback; translates multiselect fields into checkboxes. */ function betterselect_process($element, $edit, $form_state, $complete_form) { if (isset($element['#multiple']) && $element['#multiple'] == TRUE && !(variable_get('betterselect_node_form_only', FALSE) == TRUE && $complete_form['#id'] != 'node-form')) { // To handle deselection of checkboxes in exposed Views-filters we need this if ((substr($complete_form['#id'],0,18) == 'views-exposed-form') && isset($element['#value'][0])) { $element['#value'] = array(); } // If we're dealing with taxonomy, fix the option titles. if (is_object($element['#options'][0])) { // Build new array of options in format that theme_checkboxes expects. $options = array(); $defaults = array(); foreach ($element['#options'] as $option) { if (is_array($option->option)) { foreach ($option->option as $tid => $name) { $options[$tid] = check_plain($name); } } } $element['#options'] = $options; } // We now check that the element's options are correct. If they're not in // the right format, we abort. foreach($element['#options'] as $key => $val) { if (!is_numeric($key) || !is_string($val)) { return $element; } } // The default value should be an array, if it isn't expand_checkboxes() // will make it one. if (isset($element['#default_value']) && is_array($element['#default_value']) && count($element['#default_value'])) { // Fix the value arrays; checkboxes are the exact inverse of multiselect, // apparently for vindictive fun. // First make sure there's at least 1 non-blank array element $temp = $element['#default_value']; $temp = array_shift($element['#default_value']); if (!empty($temp)) { $element['#default_value'] = array_flip($element['#default_value']); $element['#value'] = array_flip($element['#value']); } } // Place options in a scrollable or non-scrollable div $div_class = variable_get('betterselect_scroll', FALSE) ? 'form-checkboxes-scroll' : 'form-checkboxes-noscroll'; $element['#attributes'] = array('class' => $div_class); // Switch display to checkboxes instead. $element['#type'] = 'checkboxes'; unset($element['#theme']); $element = expand_checkboxes($element); // Hide the silly "None" option. (assumes array element with a blank key is the "None" option) if (!$element['#required'] && is_array($element[''])) { $element['']['#prefix'] = '
'; } // Include the JS and CSS files. static $path; if (!isset($path)) { $path = drupal_get_path('module', 'betterselect'); drupal_add_css($path . '/betterselect.css'); drupal_add_js($path . '/betterselect.js'); } // Add classes to items that indicate depth, for taxonomy, useful for // styling parent terms differently. if (variable_get('betterselect_add_depth_classes', FALSE)) { $prev = NULL; $prev_depth = 0; foreach (element_children($element) as $key) { $title = $element[$key]['#title']; $trim_title = ltrim($title, '-'); $depth = strlen($title) - strlen($trim_title); $extra_class = 'checkbox-depth-' . $depth; $element[$key]['#prefix'] = '