Projet

Général

Profil

Paste
Télécharger (6,48 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / themes / bootstrap / js / misc / _vertical-tabs.js @ 7547bb19

1

    
2
(function ($) {
3

    
4
/**
5
 * This script transforms a set of fieldsets into a stack of vertical
6
 * tabs. Another tab pane can be selected by clicking on the respective
7
 * tab.
8
 *
9
 * Each tab may have a summary which can be updated by another
10
 * script. For that to work, each fieldset has an associated
11
 * 'verticalTabCallback' (with jQuery.data() attached to the fieldset),
12
 * which is called every time the user performs an update to a form
13
 * element inside the tab pane.
14
 */
15
Drupal.behaviors.verticalTabs = {
16
  attach: function (context) {
17
    $('.vertical-tabs-panes', context).once('vertical-tabs', function () {
18
      $(this).addClass('tab-content');
19
      var focusID = $(':hidden.vertical-tabs-active-tab', this).val();
20
      if (typeof focusID === 'undefined' || !focusID.length) {
21
        focusID = false;
22
      }
23
      var tab_focus;
24

    
25
      // Check if there are some fieldsets that can be converted to vertical-tabs
26
      var $fieldsets = $('> fieldset', this);
27
      if ($fieldsets.length == 0) {
28
        return;
29
      }
30

    
31
      // Create the tab column.
32
      var tab_list = $('<ul class="nav nav-tabs vertical-tabs-list"></ul>');
33
      $(this).wrap('<div class="tabbable tabs-left vertical-tabs clearfix"></div>').before(tab_list);
34

    
35
      // Transform each fieldset into a tab.
36
      $fieldsets.each(function () {
37
        var vertical_tab = new Drupal.verticalTab({
38
          title: $('> legend', this).text(),
39
          fieldset: $(this)
40
        });
41
        tab_list.append(vertical_tab.item);
42
        $(this)
43
          .removeClass('collapsible collapsed panel panel-default')
44
          .addClass('tab-pane vertical-tabs-pane')
45
          .data('verticalTab', vertical_tab)
46
          .find('> legend').remove();
47
        $(this).find('> div').removeClass('panel-collapse collapse').addClass('fade');
48
        if (this.id === focusID) {
49
          tab_focus = $(this);
50
        }
51
      });
52

    
53
      $('> li:first', tab_list).addClass('first');
54
      $('> li:last', tab_list).addClass('last');
55

    
56
      if (!tab_focus) {
57
        // If the current URL has a fragment and one of the tabs contains an
58
        // element that matches the URL fragment, activate that tab.
59
        if (window.location.hash && $(this).find(window.location.hash).length) {
60
          tab_focus = $(this).find(window.location.hash).closest('.vertical-tabs-pane');
61
        }
62
        else {
63
          tab_focus = $('> .vertical-tabs-pane:first', this);
64
        }
65
      }
66
      if (tab_focus.length) {
67
        tab_focus.data('verticalTab').focus();
68
      }
69
    });
70
  }
71
};
72

    
73
/**
74
 * The vertical tab object represents a single tab within a tab group.
75
 *
76
 * @param settings
77
 *   An object with the following keys:
78
 *   - title: The name of the tab.
79
 *   - fieldset: The jQuery object of the fieldset that is the tab pane.
80
 */
81
Drupal.verticalTab = function (settings) {
82
  var self = this;
83
  $.extend(this, settings, Drupal.theme('verticalTab', settings));
84

    
85
  this.link.click(function () {
86
    self.focus();
87
  });
88

    
89
  // Keyboard events added:
90
  // Pressing the Enter key will open the tab pane.
91
  this.link.keydown(function(event) {
92
    if (event.keyCode == 13) {
93
      self.focus();
94
      // Set focus on the first input field of the visible fieldset/tab pane.
95
      $("fieldset.vertical-tabs-pane :input:visible:enabled:first").focus();
96
      return false;
97
    }
98
  });
99

    
100
  this.fieldset
101
    .bind('summaryUpdated', function () {
102
      self.updateSummary();
103
    })
104
    .trigger('summaryUpdated');
105
};
106

    
107
Drupal.verticalTab.prototype = {
108
  /**
109
   * Displays the tab's content pane.
110
   */
111
  focus: function () {
112
    this.fieldset
113
      .siblings('fieldset.vertical-tabs-pane')
114
        .each(function () {
115
          $(this).removeClass('active').find('> div').removeClass('in');
116
          var tab = $(this).data('verticalTab');
117
          tab.item.removeClass('selected');
118
        })
119
        .end()
120
        .addClass('active')
121
        .siblings(':hidden.vertical-tabs-active-tab')
122
        .val(this.fieldset.attr('id'));
123
    this.fieldset.find('> div').addClass('in');
124
    this.fieldset.data('verticalTab').item.find('a').tab('show');
125
    this.item.addClass('selected');
126
    // Mark the active tab for screen readers.
127
    $('#active-vertical-tab').remove();
128
    this.link.append('<span id="active-vertical-tab" class="element-invisible">' + Drupal.t('(active tab)') + '</span>');
129
  },
130

    
131
  /**
132
   * Updates the tab's summary.
133
   */
134
  updateSummary: function () {
135
    this.summary.html(this.fieldset.drupalGetSummary());
136
  },
137

    
138
  /**
139
   * Shows a vertical tab pane.
140
   */
141
  tabShow: function () {
142
    // Display the tab.
143
    this.item.show();
144
    // Update .first marker for items. We need recurse from parent to retain the
145
    // actual DOM element order as jQuery implements sortOrder, but not as public
146
    // method.
147
    this.item.parent().children('.vertical-tab-button').removeClass('first')
148
      .filter(':visible:first').addClass('first');
149
    // Display the fieldset.
150
    this.fieldset.removeClass('vertical-tab-hidden');
151
    // Focus this tab.
152
    this.focus();
153
    return this;
154
  },
155

    
156
  /**
157
   * Hides a vertical tab pane.
158
   */
159
  tabHide: function () {
160
    // Hide this tab.
161
    this.item.hide();
162
    // Update .first marker for items. We need recurse from parent to retain the
163
    // actual DOM element order as jQuery implements sortOrder, but not as public
164
    // method.
165
    this.item.parent().children('.vertical-tab-button').removeClass('first')
166
      .filter(':visible:first').addClass('first');
167
    // Hide the fieldset.
168
    this.fieldset.addClass('vertical-tab-hidden');
169
    // Focus the first visible tab (if there is one).
170
    var $firstTab = this.fieldset.siblings('.vertical-tabs-pane:not(.vertical-tab-hidden):first');
171
    if ($firstTab.length) {
172
      $firstTab.data('verticalTab').focus();
173
    }
174
    return this;
175
  }
176
};
177

    
178
/**
179
 * Theme function for a vertical tab.
180
 *
181
 * @param settings
182
 *   An object with the following keys:
183
 *   - title: The name of the tab.
184
 * @return
185
 *   This function has to return an object with at least these keys:
186
 *   - item: The root tab jQuery element
187
 *   - link: The anchor tag that acts as the clickable area of the tab
188
 *       (jQuery version)
189
 *   - summary: The jQuery element that contains the tab summary
190
 */
191
Drupal.theme.prototype.verticalTab = function (settings) {
192
  var tab = {};
193
  tab.item = $('<li class="vertical-tab-button" tabindex="-1"></li>')
194
    .append(tab.link = $('<a href="#' + settings.fieldset[0].id + '" data-toggle="tab"></a>')
195
      .append(tab.title = $('<span></span>').text(settings.title))
196
      .append(tab.summary = $('<div class="summary"></div>')
197
    )
198
  );
199
  return tab;
200
};
201

    
202
})(jQuery);