Index: elements.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/elements/elements.module,v retrieving revision 1.1.2.2.2.9.2.2 diff -u -p -r1.1.2.2.2.9.2.2 elements.module --- elements.module 12 Dec 2010 00:24:16 -0000 1.1.2.2.2.9.2.2 +++ elements.module 2 Feb 2011 18:26:42 -0000 @@ -51,6 +51,12 @@ function elements_element_info() { '#theme' => 'rangefield', '#theme_wrappers' => array('form_element'), ); + $types['horizontal_tabs'] = array( + '#theme_wrappers' => array('horizontal_tabs'), + '#default_tab' => '', + '#pre_render' => array('form_pre_render_fieldset'), + '#process' => array('form_process_horizontal_tabs'), + ); return $types; } @@ -105,6 +111,10 @@ function elements_theme() { 'render element' => 'element', 'file' => 'elements.theme.inc', ), + 'horizontal_tabs' => array( + 'render element' => 'element', + 'file' => 'elements.theme.inc', + ), ); } @@ -154,3 +164,30 @@ function form_process_placeholder($eleme } 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 vertical 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'], + ); + + // Add JS and CSS necessary for the horizontal tabs + $element['#attached']['js'][] = drupal_get_path('module', 'elements') . '/js/horizontal_tab.js'; + $element['#attached']['css'][] = drupal_get_path('module', 'elements') . '/css/horizontal_tab.css'; + + return $element; +} Index: elements.theme.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/elements/Attic/elements.theme.inc,v retrieving revision 1.1.4.2 diff -u -p -r1.1.4.2 elements.theme.inc --- elements.theme.inc 11 Dec 2010 22:32:35 -0000 1.1.4.2 +++ elements.theme.inc 2 Feb 2011 18:26:42 -0000 @@ -142,3 +142,21 @@ 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 of the element. + * Properties used: #children. + * + * @ingroup themeable + */ +function theme_horizontal_tabs($variables) { + $element = $variables['element']; + + $output = '

' . t('Horizontal Tabs') . '

'; + $output .= '
' . $element['#children'] . '
'; + return $output; +} Index: css/horizontal_tab.css =================================================================== RCS file: css/horizontal_tab.css diff -N css/horizontal_tab.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ css/horizontal_tab.css 2 Feb 2011 18:26:42 -0000 @@ -0,0 +1,54 @@ +/* $Id:$ */ + +.horizontal-tabs-processed .horizontal-tabs-pane { + clear: both; + margin-top: 0; + padding: 0; +} + +.horizontal-tabs-processed .horizontal-tabs-pane > legend { + display: none; +} + +.horizontal-tabs .horizontal-tabs-list { + margin: 0; +} + +.horizontal-tab-button { + list-style: none; +} + +.horizontal-tab-button { + float: left; /* LTR */ + margin-right: 4px; /* LTR */ + position: relative; + top: 1px; + z-index: 0; +} + +.horizontal-tab-button.last { + margin-right: 0; +} + +.horizontal-tab-button a { + background: #efefef; + border: 1px solid #d5d5d5; + border-bottom-color: #ccc; + display: inline-block; + padding: 1px 5px 3px; + color: #000; +} + +.horizontal-tab-button a:hover { + background: #d5d5d5; + text-decoration: none; +} + +.horizontal-tab-button.selected a, +.horizontal-tab-button.selected a:active { + background: #fff; + border: 1px solid #ccc; + border-bottom-color: #fff; + outline: none; + z-index: 1; +} Index: js/horizontal_tab.js =================================================================== RCS file: js/horizontal_tab.js diff -N js/horizontal_tab.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ js/horizontal_tab.js 2 Feb 2011 18:26:42 -0000 @@ -0,0 +1,156 @@ +// $Id:$ + +(function ($) { + +/** + * Copy of the functionality of vertical tabs in Drupal 7 core + */ +Drupal.behaviors.horizontalTabs = { + attach: function (context) { + $('.horizontal-tabs-panes', context).once('horizontal-tabs', function () { + var focusID = $(':hidden.horizontal-tabs-active-tab', this).val(); + var tab_focus; + + // Check if there are some fieldsets that can be converted to horizontal-tabs + var $fieldsets = $('> fieldset', this); + if ($fieldsets.length == 0) { + return; + } + + // Create the tab column. + var tab_list = $(''); + $(this).wrap('
').before(tab_list); + + // Transform each fieldset into a tab. + $fieldsets.each(function () { + var horizontal_tab = new Drupal.horizontalTab({ + title: $('> legend', this).text(), + fieldset: $(this) + }); + tab_list.append(horizontal_tab.item); + $(this) + .removeClass('collapsible collapsed') + .addClass('horizontal-tabs-pane') + .data('horizontalTab', horizontal_tab); + if (this.id == focusID) { + tab_focus = $(this); + } + }); + + $('> li:first', tab_list).addClass('first'); + $('> li:last', tab_list).addClass('last'); + + if (!tab_focus) { + // If the current URL has a fragment and one of the tabs contains an + // element that matches the URL fragment, activate that tab. + if (window.location.hash && $(window.location.hash, this).length) { + tab_focus = $(window.location.hash, this).closest('.horizontal-tabs-\n\ +\n\ +pane'); + } + else { + tab_focus = $('> .horizontal-tabs-pane:first', this); + } + } + if (tab_focus.length) { + tab_focus.data('horizontalTab').focus(); + } + + // Set a min width so the tabs won't float below + var minWidth = 0; + $('> li', tab_list).each(function () { + var outer = $(this).outerWidth(true); + minWidth = minWidth + outer; + }); + $(this).parent().css('min-width', minWidth); + + }); + } +}; + +/** + * The horizontal tab object represents a single tab within a tab group. + * + * @param settings + * An object with the following keys: + * - title: The name of the tab. + * - fieldset: The jQuery object of the fieldset that is the tab pane. + */ +Drupal.horizontalTab = function (settings) { + var self = this; + $.extend(this, settings, Drupal.theme('horizontalTab', settings)); + + this.link.click(function () { + self.focus(); + return false; + }); + + // Keyboard events added: + // Pressing the Enter key will open the tab pane. + this.link.keydown(function(event) { + if (event.keyCode == 13) { + self.focus(); + // Set focus on the first input field of the visible fieldset/tab pane. + $("fieldset.horizontal-tabs-pane :input:visible:enabled:first").focus(); + return false; + } + }); + + // Pressing the Enter key lets you leave the tab again. + this.fieldset.keydown(function(event) { + // Enter key should not trigger inside