Projet

Général

Profil

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

root / drupal7 / sites / all / themes / adaptivetheme / at_core / scripts / vertical-tabs.js @ 74f6bef0

1
/* This is overridden to fix an annoying issue in webkit browsers. */
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
      var focusID = $(':hidden.vertical-tabs-active-tab', this).val();
19
      var tab_focus;
20

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

    
27
      // Create the tab column.
28
      var tab_list = $('<ul class="vertical-tabs-list"></ul>');
29
      $(this).wrap('<div class="vertical-tabs clearfix"></div>').before(tab_list);
30

    
31
      // Transform each fieldset into a tab.
32
      $fieldsets.each(function () {
33
        var vertical_tab = new Drupal.verticalTab({
34
          title: $('> legend', this).text(),
35
          fieldset: $(this)
36
        });
37
        tab_list.append(vertical_tab.item);
38
        $(this)
39
          .removeClass('collapsible collapsed')
40
          .addClass('vertical-tabs-pane')
41
          .data('verticalTab', vertical_tab);
42
        if (this.id == focusID) {
43
          tab_focus = $(this);
44
        }
45
      });
46

    
47
      $('> li:first', tab_list).addClass('first');
48
      $('> li:last', tab_list).addClass('last');
49

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

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

    
79
  this.link.click(function () {
80
    self.focus();
81
    return false;
82
  });
83

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

    
95
  // Pressing the Enter key lets you leave the tab again.
96
  this.fieldset.keydown(function(event) {
97
    // Enter key should not trigger inside <textarea> to allow for multi-line entries.
98
    if (event.keyCode == 13 && event.target.nodeName != "TEXTAREA") {
99
      // Set focus on the selected tab button again.
100
      $(".vertical-tab-button.selected a").focus();
101
      return false;
102
    }
103
  });
104

    
105
  this.fieldset
106
    .bind('summaryUpdated', function () {
107
      self.updateSummary();
108
    })
109
    .trigger('summaryUpdated');
110
};
111

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

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

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

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

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

    
209
})(jQuery);