' . t('About') . ''; $output .= '

' . t('Chosen uses the Chosen jQuery plugin to make your < select > elements more user-friendly.') . '

'; $output .= '

' . t('Usage') . '

'; $output .= '

' . t('Configure at: admin/config/user-interface/chosen', array('@structure_types' => base_path() . 'admin/config/user-interface/chosen')) . '

'; return $output; } } /** * Implements hook_menu(). */ function chosen_menu() { $items = array(); $items['admin/config/user-interface/chosen'] = array( 'title' => 'Chosen', 'description' => 'Configuration for Chosen plugin', 'page callback' => 'drupal_get_form', 'page arguments' => array('chosen_admin_settings'), 'access arguments' => array('administer site configuration'), 'file' => 'chosen.admin.inc', ); return $items; } /** * Implements hook_field_widget_info_alter(). * * A list of settings needed by Chosen module for widgets. */ function chosen_field_widget_info_alter(&$info) { $widget_defaults = array( 'options_select' => '', 'select_or_other' => '', 'date_combo' => 0, ); foreach ($widget_defaults as $widget => $default) { if (isset($info[$widget])) { $info[$widget]['settings']['apply_chosen'] = $default; } } } /** * Implements hook_form_FORM_ID_alter(). */ function chosen_form_field_ui_field_edit_form_alter(&$form, $form_state) { if (empty($form['#field']['locked']) && isset($form['#instance']['widget']['settings']['apply_chosen'])) { $form['instance']['widget']['settings']['apply_chosen'] = array( '#type' => 'select', '#title' => t('Apply Chosen to the select fields in this widget?'), '#options' => array( 0 => t('Do not apply'), 1 => t('Apply'), ), '#default_value' => $form['#instance']['widget']['settings']['apply_chosen'], '#disabled' => !chosen_get_chosen_path(), '#empty_option' => t('No preference'), '#empty_value' => '', '#chosen' => FALSE, ); } } /** * Implements hook_field_widget_form_alter(). */ function chosen_field_widget_form_alter(&$element, &$form_state, $context) { if (isset($context['instance']['widget']['settings']['apply_chosen'])) { $value = $context['instance']['widget']['settings']['apply_chosen']; if ($value === '') { return; } else { $element['#chosen'] = !empty($value); } } } /** * Implements hook_library(). */ function chosen_library() { global $theme; $library_path = chosen_get_chosen_path(); $info['chosen'] = array( 'title' => 'Chosen', 'website' => CHOSEN_WEBSITE_URL, 'version' => '1.1.0', 'js' => array( $library_path . '/chosen.jquery.min.js' => array(), ), ); $css_disabled_themes = variable_get('chosen_disabled_themes', array()); // Only add the Chosen CSS if it is not disabled for the active theme. if (!in_array($theme, $css_disabled_themes, TRUE)) { $css = $library_path . '/chosen.css'; if (!file_exists($css)) { $css = $library_path . '/chosen.min.css'; } $info['chosen']['css'] = array($css => array()); } // All the settings that are actually passed through into the chosen() // function are contained in this array. $options = array( 'allow_single_deselect' => (bool) variable_get('chosen_allow_single_deselect', FALSE), 'disable_search' => (bool) variable_get('chosen_disable_search', FALSE), 'disable_search_threshold' => (int) variable_get('chosen_disable_search_threshold', 0), 'search_contains' => (bool) variable_get('chosen_search_contains', FALSE), 'placeholder_text_multiple' => variable_get('chosen_placeholder_text_multiple', t('Choose some options')), 'placeholder_text_single' => variable_get('chosen_placeholder_text_single', t('Choose an option')), 'no_results_text' => variable_get('chosen_no_results_text', t('No results match')), 'inherit_select_classes' => TRUE, ); $module_path = drupal_get_path('module', 'chosen'); $info['drupal.chosen'] = array( 'title' => 'Drupal Chosen integration', 'website' => 'https://drupal.org/project/chosen', 'version' => '1.1.0', 'js' => array( $module_path . '/chosen.js' => array( 'group' => JS_DEFAULT, 'weight' => 100, ), array( 'data' => array( 'chosen' => array( 'selector' => variable_get('chosen_jquery_selector', 'select:visible'), 'minimum_single' => (int) variable_get('chosen_minimum_single', 20), 'minimum_multiple' => (int) variable_get('chosen_minimum_multiple', 20), 'minimum_width' => (int) variable_get('chosen_minimum_width', ''), 'options' => $options, ), ), 'type' => 'setting', ), ), 'css' => array( $module_path . '/css/chosen-drupal.css' => array(), ), 'dependencies' => array( array('system', 'jquery.once'), array('chosen', 'chosen'), ), ); return $info; } /** * Implements hook_element_info_alter(). */ function chosen_element_info_alter(&$info) { $info['select']['#pre_render'][] = 'chosen_pre_render_select'; if (module_exists('date')) { $info['date_combo']['#pre_render'][] = 'chosen_pre_render_date_combo'; } if (module_exists('select_or_other')) { $info['select_or_other']['#pre_render'][] = 'chosen_pre_render_select_or_other'; } } /** * Render API callback: Apply Chosen to a select element. */ function chosen_pre_render_select($element) { // Exclude chosen from theme other than admin. global $theme, $language; $is_admin = path_is_admin(current_path()) || current_path() == 'system/ajax' || $theme == variable_get('admin_theme'); $chosen_include = variable_get('chosen_include', CHOSEN_INCLUDE_EVERYWHERE); if ($chosen_include != CHOSEN_INCLUDE_EVERYWHERE && $is_admin == $chosen_include) { return $element; } // If the #chosen FAPI property is set, then add the appropriate class. if (isset($element['#chosen'])) { if (!empty($element['#chosen'])) { // Element has opted-in for Chosen, ensure the library gets added. $element['#attributes']['class'][] = 'chosen-enable'; } else { $element['#attributes']['class'][] = 'chosen-disable'; // Element has opted-out of Chosen. Do not add the library now. return $element; } } elseif (isset($element['#attributes']['class']) && is_array($element['#attributes']['class'])) { if (array_intersect($element['#attributes']['class'], array('chosen-disable'))) { // Element has opted-out of Chosen. Do not add the library now. return $element; } elseif (array_intersect($element['#attributes']['class'], array('chosen-enable', 'chosen-widget'))) { // Element has opted-in for Chosen, ensure the library gets added. // @todo Remove support for the deprecated chosen-widget class. } } else { // Neither the #chosen property was set, nor any chosen classes found. // This element still might match the site-wide critera, so add the library. } if (isset($element['#field_name']) && !empty($element['#multiple'])) { // Remove '_none' from multi-select options. unset($element['#options']['_none']); $field = field_info_field($element['#field_name']); if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && $field['cardinality'] > 1) { $element['#attributes']['data-cardinality'] = $field['cardinality']; } } // Right to Left Support. if ($language->direction == 1) { $element['#attributes']['class'][] = 'chosen-rtl'; } $element['#attached']['library'][] = array('chosen', 'drupal.chosen'); return $element; } /** * Render API callback: Apply Chosen to a date_combo element. */ function chosen_pre_render_date_combo($element) { // Because the date_combo field contains many different select elements, we // need to recurse down and apply the FAPI property to each one. if (isset($element['#chosen'])) { chosen_element_apply_property_recursive($element, $element['#chosen']); } return $element; } /** * Render API callback: Apply Chosen to a select_or_other element. */ function chosen_pre_render_select_or_other($element) { if ($element['#select_type'] == 'select' && isset($element['#chosen'])) { $element['select']['#chosen'] = $element['#chosen']; } return $element; } /** * Recurse through an element to apply the chosen property to any select fields. */ function chosen_element_apply_property_recursive(array &$element, $chosen_value = NULL) { if (!isset($chosen_value)) { if (isset($element['#chosen'])) { $chosen_value = $element['#chosen']; } else { return; } } if (isset($element['#type']) && $element['#type'] == 'select') { $element['#chosen'] = $chosen_value; } foreach (element_children($element) as $key) { chosen_element_apply_property_recursive($element[$key], $chosen_value); } } /** * Get the location of the chosen library. * * @return mixed * The location of the library, or FALSE if the library isn't installed. */ function chosen_get_chosen_path() { if (function_exists('libraries_get_path')) { return libraries_get_path('chosen'); } // The following logic is taken from libraries_get_libraries() $searchdir = array(); // Similar to 'modules' and 'themes' directories inside an installation // profile, installation profiles may want to place libraries into a // 'libraries' directory. $searchdir[] = 'profiles/' . drupal_get_profile() . '/libraries'; // Always search sites/all/libraries. $searchdir[] = 'sites/all/libraries'; // Also search sites//*. $searchdir[] = conf_path() . '/libraries'; foreach ($searchdir as $dir) { if (file_exists($dir . '/chosen/chosen.jquery.min.js')) { return $dir . '/chosen'; } } return FALSE; }