$element)); * but you can also use static HTML. (See README.txt) * * Fieldset helper state manager: * * - The 'state manager' stores the state of all collapsible fieldsets in a * cookie. * * - The state manager dramatically reduces the cookie's size, by converting the * fieldset's element #id and its related path to an auto incremented numeric id. * * - The state management is controlled by the fieldset_helper_state_manager * PHP functions and the FieldsetHelperStateManager JavaScript object which * isolates the API so that it can copied, renamed, and re-used. * * * Related discussions * - @link http://drupal.org/node/114130 Is it possible to get Fieldset Collapsed/Collapsible to remember settings? @endlink * - @link http://drupal.org/node/209006 would be nice to save/show fieldset states @endlink * - @link http://drupal.org/node/198529 In modules listing: collapse fieldsets @endlink * - @link http://drupal.org/node/49103 Give fieldsets an id @endlink * - @link http://drupal.org/node/118343 Adding a collapsible fieldset to your nodes @endlink * - @link http://drupal.org/node/321779 Use Drupal JS Libraries : Your own collapsible fieldset @endlink * * Similar modules * - @link http://drupal.org/project/autosave Autosave @endlink * - @link http://drupal.org/project/util Utility @endlink */ module_load_include('inc', 'fieldset_helper', 'fieldset_helper.theme'); //////////////////////////////////////////////////////////////////////////////// // Hooks //////////////////////////////////////////////////////////////////////////////// /** * Implements hook_permission(). */ function fieldset_helper_permission() { return array( 'save fieldset state' => array( 'title' => t('Save fieldset state'), 'description' => t('Allows users to save the state of collapsible fieldsets.'), ), ); } /** * Implements hook_menu(). */ function fieldset_helper_menu() { $items['admin/config/user-interface/fieldset_helper'] = array( 'title' => 'Fieldset helper', 'description' => 'Settings to save FAPI collapsible fieldset state', 'page callback' => 'drupal_get_form', 'page arguments' => array('fieldset_helper_admin_settings'), 'file' => 'fieldset_helper.admin.inc', 'access arguments' => array('administer site configuration'), 'type' => MENU_NORMAL_ITEM, ); $items['admin/config/user-interface/fieldset_helper/view'] = array( 'title' => 'Settings', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0, ); $items['admin/config/user-interface/fieldset_helper/test'] = array( 'title' => 'Test', 'description' => 'Test page for saving FAPI collapsible fieldset state', 'page callback' => 'fieldset_helper_test', 'file' => 'fieldset_helper.admin.inc', 'access arguments' => array('administer site configuration'), 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); return $items; } /** * Implements hook_fieldset_helper_path_alter(). */ function fieldset_helper_fieldset_helper_path_alter(&$path) { // Force all node form (add and edit) fieldsets to share their state. if (variable_get('fieldset_helper_node_form_state', 1) == 1) { if (preg_match('#^(node/[^/]+/edit|node/add/[^/]+)$#', $path)) { $path = 'node/form'; } } } //////////////////////////////////////////////////////////////////////////////// // Alter js function. //////////////////////////////////////////////////////////////////////////////// /** * Implements hook_js_alter(). */ function fieldset_helper_js_alter(&$javascript) { static $altered; if ($altered !== TRUE && fieldset_helper_number_of_collapsible_fieldset() !== 0) { // Immediately set $altered to avoid recursions when using drupal_add_js(). $altered = TRUE; // Make sure to add 'misc/form.js'. if (!isset($javascript['misc/form.js'])) { drupal_add_js('misc/form.js'); } // Make sure to add 'misc/collapse.js'. if (!isset($javascript['misc/collapse.js'])) { drupal_add_js('misc/collapse.js'); } // Add 'fieldset_helper.js'. $fieldset_helper_js = drupal_get_path('module', 'fieldset_helper') . '/fieldset_helper.js'; if (!isset($javascript[$fieldset_helper_js])) { drupal_add_js($fieldset_helper_js ); } // Add settings. (includes lookups ids and cookie duration) $settings['fieldset_helper_state_manager'] = array( 'ids' => fieldset_helper_state_manager_get_lookup_id(), 'cookie_duration' => variable_get('fieldset_helper_cookie_duration', 0), ); drupal_add_js($settings, 'setting'); } } //////////////////////////////////////////////////////////////////////////////// // General and utility functions //////////////////////////////////////////////////////////////////////////////// /** * Get default collapsible attribute for the current path. */ function fieldset_helper_default_collapsible() { static $default_collapsible; if (isset($default_collapsible)) { return $default_collapsible; } $pages = variable_get('fieldset_helper_default_collapsible_pages', '*'); if (empty($pages)) { $default_collapsible = FALSE; } elseif (trim($pages) == '*') { $default_collapsible = TRUE; } else { $default_collapsible = drupal_match_path($_GET['q'], $pages); } return $default_collapsible; } /** * Get default collapsed state for the current page. */ function fieldset_helper_default_collapsed() { static $default_collapsed; if (isset($default_collapsed)) { return $default_collapsed; } $pages = variable_get('fieldset_helper_default_collapsed_pages', 'admin/modules'); if (empty($pages)) { $default_collapsed = FALSE; } elseif (trim($pages) == '*') { $default_collapsed = TRUE; } else { $default_collapsed = drupal_match_path($_GET['q'], $pages); } return $default_collapsed; } /** * Track the number of collapsible fieldsets on the page. */ function fieldset_helper_number_of_collapsible_fieldset($count = 0, $reset = FALSE) { static $number_of_collapsible_fieldset; if (!isset($number_of_collapsible_fieldset) || $reset === TRUE) { $number_of_collapsible_fieldset = 0; } $number_of_collapsible_fieldset += $count; return $number_of_collapsible_fieldset; } //////////////////////////////////////////////////////////////////////////////// // State manager functions. //////////////////////////////////////////////////////////////////////////////// /** * Check if a path matches any pattern in a set of patterns. * * @return * The path to save current page's element to. */ function fieldset_helper_state_manager_get_path() { static $path; if (isset($path)) { return $path; } $path = $_GET['q']; if ($pages = variable_get('fieldset_helper_global_pages', '')) { $pages = preg_split('/\s+/', $pages); foreach ($pages as $page) { $pattern = '/^' . str_replace('\*', '.*', preg_quote($page, '/') ) . '$/'; if (preg_match($pattern, $path)) { $path = $page; break; } } } // Run all hook implementations for hook_fieldset_helper_path_alter(). foreach (module_implements('fieldset_helper_path_alter') as $module) { $function = $module . '_fieldset_helper_path_alter'; $function($path); } return $path; } /** * Check if a fieldset id matches any global id patterns. * * @param $element_id * The DOM element id. * @param $path * Default path if no match is found. * @return * The elements path (*, $_GET['q'], or custom). */ function fieldset_helper_state_manager_get_element_path($element_id, $path) { static $global_patterns; if (!isset($global_patterns )) { $global_ids = variable_get('fieldset_helper_global_ids', ''); $global_patterns = '/^(' . preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/'), array('|', '.*'), preg_quote($global_ids, '/')) . ')$/'; } $path = preg_match($global_patterns, $element_id) ? '*' : $path; // Run all hook implementations for hook_fieldset_helper_element_path_alter(). foreach (module_implements('fieldset_helper_element_path_alter') as $module) { $function = $module . '_fieldset_helper_element_path_alter'; $function($element_id, $path); } return $path; } /** * Get the lookup id for the $element_id in the current path. * * @param $element_id * The DOM element id. * @return * The numeric auto generated look up id for the $element_id. If $element_id * is not set then the entire lookup id table for the current page will returned. */ function fieldset_helper_state_manager_get_lookup_id($element_id = NULL) { static $lookup_id_table; $path = fieldset_helper_state_manager_get_path(); // Load existing lookup ids for the current path from the database. if (!isset($lookup_id_table)) { $lookup_id_table = array(); // Fetch lookup records for the current path. Use sorting to make sure global path (*) are last. $result = db_query("SELECT id, element_id FROM {fieldset_helper_state_manager} WHERE path=:path OR path='*' ORDER BY path DESC", array(':path' => $path)); foreach ($result as $record) { $lookup_id_table[ $record->element_id ] = $record->id; } } // Create a new lookup id for element_id's not associated with the lookup id table. if ( $element_id != NULL && !isset($lookup_id_table[$element_id]) ) { // Get element path. $element_path = fieldset_helper_state_manager_get_element_path($element_id, $path); // Get id for path and element_id combination. $lookup_id = db_insert('fieldset_helper_state_manager') ->fields(array( 'path' => $element_path, 'element_id' => $element_id, )) ->execute(); $lookup_id_table[$element_id] = $lookup_id; } // Return the look up id for the element id. return ($element_id == NULL) ? $lookup_id_table : $lookup_id_table[$element_id]; } /** * Clear all the store lookup id for every form. */ function fieldset_helper_state_manager_clear_lookup_ids() { drupal_set_message(t('Fieldset lookup ids cleared.')); db_delete('fieldset_helper_state_manager')->execute(); } /** * Get an associated array for lookup id and the element's state (1 or 0) from $_COOKIE['fieldset_helper_state_manager']. * * @param $clear * Optional boolean when set to TRUE will clear any cached cookie states. */ function fieldset_helper_state_manager_get_cookie_states($clear = FALSE) { static $states; if (isset($states) && $clear == FALSE) { return $states; } $states = array(); if (!isset($_COOKIE['fieldset_helper_state_manager'])) { return $states; } else { $values = explode('_', $_COOKIE['fieldset_helper_state_manager']); foreach ($values as $value) { $params = explode('.', $value); $states[ $params[0] ] = ($params[1] == '1') ? TRUE : FALSE ; } return $states; } } /** * Get fieldset's collapsed state. * * @param $element_id * The DOM element id. * @param $default_value * Boolean for default state value */ function fieldset_helper_state_manager_get_state($element_id, $default_value = FALSE) { // Always return the default value is state management is disabled for anonymous. if (user_is_anonymous() && variable_get('fieldset_helper_disable_state_anonymous', 0) == 1) { return $default_value; } // Get fieldset states and lookup ids $states = fieldset_helper_state_manager_get_cookie_states(); $lookup_id = fieldset_helper_state_manager_get_lookup_id($element_id); // Return collapsed boolean value. if ( isset($states[$lookup_id])) { return ($states[$lookup_id]) ? TRUE : FALSE; } else { return ($default_value) ? TRUE : FALSE; } }