diff --git a/elements.module b/elements.module index ed66a30..7d025cc 100644 --- a/elements.module +++ b/elements.module @@ -51,11 +51,44 @@ function elements_element_info() { '#theme' => 'rangefield', '#theme_wrappers' => array('form_element'), ); + $types['horizontal_tabs'] = array( + '#theme_wrappers' => array('horizontal_tabs'), + '#default_tab' => '', + '#process' => array('form_process_horizontal_tabs'), + '#attached' => array( + 'library' => array( + array('elements', 'horizontal-tabs'), + ), + ), + ); return $types; } /** + * Implements hook_library(). + */ +function elements_library() { + + $path = drupal_get_path('module', 'elements'); + + // Horizontal Tabs. + $libraries['horizontal-tabs'] = array( + 'title' => 'Horizontal Tabs', + 'website' => 'http://drupal.org/node/323112', + 'version' => '1.0', + 'js' => array( + $path . '/horizontal-tabs/horizontal-tabs.js' => array(), + ), + 'css' => array( + $path . '/horizontal-tabs/horizontal-tabs.css' => array(), + ), + ); + + return $libraries; +} + +/** * Implements hook_element_info_alter(). */ function elements_element_info_alter(&$types) { @@ -105,6 +138,11 @@ function elements_theme() { 'render element' => 'element', 'file' => 'elements.theme.inc', ), + 'horizontal_tabs' => array( + 'arguments' => array('element' => NULL), + 'render element' => 'element', + 'file' => 'elements.theme.inc', + ), ); } @@ -154,3 +192,40 @@ function form_process_placeholder($element) { } return $element; } + +/** + * Creates a group formatted as horizontal tabs. + * + * @param $element + * An associative array containing the properties and children of the + * fieldset. + * @param $form_state + * The $form_state array for the form this horizontal tab widget belongs to. + * @return + * The processed element. + */ +function form_process_horizontal_tabs($element, &$form_state) { + // Inject a new fieldset as child, so that form_process_fieldset() processes + // this fieldset like any other fieldset. + $element['group'] = array( + '#type' => 'fieldset', + '#theme_wrappers' => array(), + '#parents' => $element['#parents'], + ); + + // The JavaScript stores the currently selected tab in this hidden + // field so that the active tab can be restored the next time the + // form is rendered, e.g. on preview pages or when form validation + // fails. + $name = implode('__', $element['#parents']); + if (isset($form_state['values'][$name . '__active_tab'])) { + $element['#default_tab'] = $form_state['values'][$name . '__active_tab']; + } + $element[$name . '__active_tab'] = array( + '#type' => 'hidden', + '#default_value' => $element['#default_tab'], + '#attributes' => array('class' => array('horizontal-tabs-active-tab')), + ); + + return $element; +} diff --git a/elements.theme.inc b/elements.theme.inc index 12b1706..b049a36 100644 --- a/elements.theme.inc +++ b/elements.theme.inc @@ -142,3 +142,22 @@ function theme_rangefield($variables) { return $output; } + +/** + * Returns HTML for an element's children fieldsets as horizontal tabs. + * + * @param $variables + * An associative array containing: + * - element: An associative array containing the properties and children of the + * fieldset. Properties used: #children. + * + * @ingroup themeable + */ +function theme_horizontal_tabs($variables) { + $element = $variables['element']; + + $output = '

' . (!empty($element['#title']) ? $element['#title'] : t('Horizontal Tabs')) . '

'; + $output .= '
' . $element['#children'] . '
'; + + return $output; +}