Projet

Général

Profil

Révision 388c412d

Ajouté par Assos Assos il y a environ 7 ans

Weekly update of contrib modules

Voir les différences:

drupal7/sites/all/themes/bootstrap/js/misc/autocomplete.js
1 1
(function ($) {
2 2

  
3
/**
4
 * Attaches the autocomplete behavior to all required fields.
5
 */
6
Drupal.behaviors.autocomplete = {
7
  attach: function (context) {
8
    var $context = $(context);
9
    var acdb = [];
10
    $context.find('input.autocomplete').once('autocomplete', function () {
11
      var uri = this.value;
12
      if (!acdb[uri]) {
13
        acdb[uri] = new Drupal.ACDB(uri);
14
      }
15
      var $input = $context.find('#' + this.id.substr(0, this.id.length - 13))
16
        .attr('autocomplete', 'OFF')
17
        .attr('aria-autocomplete', 'list');
18
      $context.find($input[0].form).submit(Drupal.autocompleteSubmit);
19
      $input.parents('.form-item')
20
        .attr('role', 'application')
21
        .append($('<span class="element-invisible" aria-live="assertive"></span>')
22
          .attr('id', $input.attr('id') + '-autocomplete-aria-live')
23
      );
24
      new Drupal.jsAC($input, acdb[uri], $context);
3
  /**
4
   * Attaches the autocomplete behavior to all required fields.
5
   */
6
  Drupal.behaviors.autocomplete = {
7
    attach: function (context) {
8
      var $context = $(context);
9
      var acdb = [];
10
      $context.find('input.autocomplete').once('autocomplete', function () {
11
        var uri = this.value;
12
        if (!acdb[uri]) {
13
          acdb[uri] = new Drupal.ACDB(uri);
14
        }
15
        var $input = $context.find('#' + this.id.substr(0, this.id.length - 13))
16
          .attr('autocomplete', 'OFF')
17
          .attr('aria-autocomplete', 'list');
18
        $context.find($input[0].form).submit(Drupal.autocompleteSubmit);
19
        $input.parents('.form-item')
20
          .attr('role', 'application')
21
          .append($('<span class="element-invisible" aria-live="assertive"></span>')
22
            .attr('id', $input.attr('id') + '-autocomplete-aria-live')
23
          );
24
        new Drupal.jsAC($input, acdb[uri], $context);
25
      });
26
    }
27
  };
28

  
29
  /**
30
   * Prevents the form from submitting if the suggestions popup is open
31
   * and closes the suggestions popup when doing so.
32
   */
33
  Drupal.autocompleteSubmit = function () {
34
    $('.form-autocomplete > .dropdown').each(function () {
35
      this.owner.hidePopup();
25 36
    });
26
  }
27
};
28

  
29
/**
30
 * Prevents the form from submitting if the suggestions popup is open
31
 * and closes the suggestions popup when doing so.
32
 */
33
Drupal.autocompleteSubmit = function () {
34
  $('.form-autocomplete > .dropdown').each(function () {
35
    this.owner.hidePopup();
36
  });
37

  
38
  // Always return true to make it possible to submit even when there was an
39
  // autocomplete suggestion list open.
37

  
38
    // Always return true to make it possible to submit even when there was an
39
    // autocomplete suggestion list open.
40 40
    return true;
41
};
42

  
43
/**
44
 * Highlights a suggestion.
45
 */
46
Drupal.jsAC.prototype.highlight = function (node) {
47
  if (this.selected) {
48
    $(this.selected).removeClass('active');
49
  }
50
  $(node).addClass('active');
51
  this.selected = node;
52
  $(this.ariaLive).html($(this.selected).html());
53
};
54

  
55
/**
56
 * Unhighlights a suggestion.
57
 */
58
Drupal.jsAC.prototype.unhighlight = function (node) {
59
  $(node).removeClass('active');
60
  this.selected = false;
61
  $(this.ariaLive).empty();
62
};
63

  
64
/**
65
 * Positions the suggestions popup and starts a search.
66
 */
67
Drupal.jsAC.prototype.populatePopup = function () {
68
  var $input = $(this.input);
69
  // Show popup.
70
  if (this.popup) {
71
    $(this.popup).remove();
72
  }
73
  this.selected = false;
74
  this.popup = $('<div class="dropdown"></div>')[0];
75
  this.popup.owner = this;
76
  $input.parent().after(this.popup);
77

  
78
  // Do search.
79
  this.db.owner = this;
80
  this.db.search(this.input.value);
81
};
82

  
83
/**
84
 * Fills the suggestion popup with any matches received.
85
 */
86
Drupal.jsAC.prototype.found = function (matches) {
87
  // If no value in the textfield, do not show the popup.
88
  if (!this.input.value.length) {
89
    return false;
90
  }
91

  
92
  // Prepare matches.
93
  var ul = $('<ul class="dropdown-menu"></ul>');
94
  var ac = this;
95
  ul.css({
96
    display: 'block',
97
    right: 0
98
  });
99
  for (var key in matches) {
100
    $('<li></li>')
101
      .html($('<a href="#"></a>').html(matches[key]).on('click', function (e) { e.preventDefault(); }))
102
      .on('mousedown', function () { ac.hidePopup(this); })
103
      .on('mouseover', function () { ac.highlight(this); })
104
      .on('mouseout', function () { ac.unhighlight(this); })
105
      .data('autocompleteValue', key)
106
      .appendTo(ul);
107
  }
108

  
109
  // Show popup with matches, if any.
110
  if (this.popup) {
111
    if (ul.children().length) {
112
      $(this.popup).empty().append(ul).show();
113
      $(this.ariaLive).html(Drupal.t('Autocomplete popup'));
41
  };
42

  
43
  /**
44
   * Highlights a suggestion.
45
   */
46
  Drupal.jsAC.prototype.highlight = function (node) {
47
    if (this.selected) {
48
      $(this.selected).removeClass('active');
49
    }
50
    $(node).addClass('active');
51
    this.selected = node;
52
    $(this.ariaLive).html($(this.selected).html());
53
  };
54

  
55
  /**
56
   * Unhighlights a suggestion.
57
   */
58
  Drupal.jsAC.prototype.unhighlight = function (node) {
59
    $(node).removeClass('active');
60
    this.selected = false;
61
    $(this.ariaLive).empty();
62
  };
63

  
64
  /**
65
   * Positions the suggestions popup and starts a search.
66
   */
67
  Drupal.jsAC.prototype.populatePopup = function () {
68
    var $input = $(this.input);
69
    // Show popup.
70
    if (this.popup) {
71
      $(this.popup).remove();
72
    }
73
    this.selected = false;
74
    this.popup = $('<div class="dropdown"></div>')[0];
75
    this.popup.owner = this;
76
    $input.parent().after(this.popup);
77

  
78
    // Do search.
79
    this.db.owner = this;
80
    this.db.search(this.input.value);
81
  };
82

  
83
  /**
84
   * Fills the suggestion popup with any matches received.
85
   */
86
  Drupal.jsAC.prototype.found = function (matches) {
87
    // If no value in the textfield, do not show the popup.
88
    if (!this.input.value.length) {
89
      return false;
90
    }
91

  
92
    // Prepare matches.
93
    var ul = $('<ul class="dropdown-menu"></ul>');
94
    var ac = this;
95
    ul.css({
96
      display: 'block',
97
      right: 0
98
    });
99
    for (var key in matches) {
100
      $('<li></li>')
101
        .html($('<a href="#"></a>').html(matches[key]).on('click', function (e) {
102
          e.preventDefault();
103
        }))
104
        .on('mousedown', function () {
105
          ac.hidePopup(this);
106
        })
107
        .on('mouseover', function () {
108
          ac.highlight(this);
109
        })
110
        .on('mouseout', function () {
111
          ac.unhighlight(this);
112
        })
113
        .data('autocompleteValue', key)
114
        .appendTo(ul);
115
    }
116

  
117
    // Show popup with matches, if any.
118
    if (this.popup) {
119
      if (ul.children().length) {
120
        $(this.popup).empty().append(ul).show();
121
        $(this.ariaLive).html(Drupal.t('Autocomplete popup'));
122
      }
123
      else {
124
        $(this.popup).css({visibility: 'hidden'});
125
        this.hidePopup();
126
      }
127
    }
128
  };
129

  
130
  /**
131
   * Finds the next sibling item.
132
   */
133
  Drupal.jsAC.prototype.findNextSibling = function (element) {
134
    var sibling = element && element.nextSibling;
135
    if (sibling && !this.validItem(sibling)) {
136
      return this.findNextSibling(sibling.nextSibling);
137
    }
138
    return sibling;
139
  };
140

  
141
  /**
142
   * Finds the previous sibling item.
143
   */
144
  Drupal.jsAC.prototype.findPreviousSibling = function (element) {
145
    var sibling = element && element.previousSibling;
146
    if (sibling && !this.validItem(sibling)) {
147
      return this.findPreviousSibling(sibling.previousSibling);
148
    }
149
    return sibling;
150
  };
151

  
152
  /**
153
   * Highlights the next suggestion.
154
   */
155
  Drupal.jsAC.prototype.selectDown = function () {
156
    var sibling = this.findNextSibling(this.selected);
157
    if (sibling) {
158
      this.highlight(sibling);
159
    }
160
    else if (this.popup) {
161
      var lis = $('li', this.popup);
162
      if (lis.length > 0) {
163
        if (this.validItem(lis[0])) {
164
          this.highlight(lis[0]);
165
        }
166
        else {
167
          this.highlight(this.findNextSibling(lis[0]));
168
        }
169
      }
170
    }
171
  };
172

  
173
  /**
174
   * Highlights the previous suggestion.
175
   */
176
  Drupal.jsAC.prototype.selectUp = function () {
177
    var sibling = this.findPreviousSibling(this.selected);
178
    if (sibling) {
179
      this.highlight(sibling);
180
    }
181
    else if (this.popup) {
182
      var lis = $('li', this.popup);
183
      if (lis.length > 0) {
184
        if (this.validItem(lis[lis.length - 1])) {
185
          this.highlight(lis[lis.length - 1]);
186
        }
187
        else {
188
          this.highlight(this.findPreviousSibling(lis[lis.length - 1]));
189
        }
190
      }
114 191
    }
115
    else {
116
      $(this.popup).css({ visibility: 'hidden' });
117
      this.hidePopup();
192
  };
193

  
194
  /**
195
   * Ensures the item is valid.
196
   */
197
  Drupal.jsAC.prototype.validItem = function (element) {
198
    return !$(element).is('.dropdown-header, .divider, .disabled');
199
  };
200

  
201
  Drupal.jsAC.prototype.setStatus = function (status) {
202
    var $throbber = $(this.input).parent().find('.glyphicon-refresh, .autocomplete-throbber').first();
203
    var throbbingClass = $throbber.is('.autocomplete-throbber') ? 'throbbing' : 'glyphicon-spin';
204
    switch (status) {
205
      case 'begin':
206
        $throbber.addClass(throbbingClass);
207
        $(this.ariaLive).html(Drupal.t('Searching for matches...'));
208
        break;
209
      case 'cancel':
210
      case 'error':
211
      case 'found':
212
        $throbber.removeClass(throbbingClass);
213
        break;
118 214
    }
119
  }
120
};
121

  
122
Drupal.jsAC.prototype.setStatus = function (status) {
123
  var $throbber = $(this.input).parent().find('.glyphicon-refresh, .autocomplete-throbber').first();
124
  var throbbingClass = $throbber.is('.autocomplete-throbber') ? 'throbbing' : 'glyphicon-spin';
125
  switch (status) {
126
    case 'begin':
127
      $throbber.addClass(throbbingClass);
128
      $(this.ariaLive).html(Drupal.t('Searching for matches...'));
129
      break;
130
    case 'cancel':
131
    case 'error':
132
    case 'found':
133
      $throbber.removeClass(throbbingClass);
134
      break;
135
  }
136
};
137

  
138
// Save the previous autocomplete prototype.
139
var oldPrototype = Drupal.jsAC.prototype;
140

  
141
/**
142
 * Override the autocomplete constructor.
143
 */
144
Drupal.jsAC = function ($input, db, context) {
145
  var ac = this;
146

  
147
  // Context is normally passed by Drupal.behaviors.autocomplete above. However,
148
  // if a module has manually invoked this method they will likely not know
149
  // about this feature and a global fallback context to document must be used.
150
  // @see https://www.drupal.org/node/2594243
151
  // @see https://www.drupal.org/node/2315295
152
  this.$context = context && $(context) || $(document);
153

  
154
  this.input = $input[0];
155
  this.ariaLive = this.$context.find('#' + this.input.id + '-autocomplete-aria-live');
156
  this.db = db;
157
  $input
158
    .keydown(function (event) { return ac.onkeydown(this, event); })
159
    .keyup(function (event) { ac.onkeyup(this, event); })
160
    .blur(function () { ac.hidePopup(); ac.db.cancel(); });
161
};
162

  
163
// Restore the previous prototype.
164
Drupal.jsAC.prototype = oldPrototype;
215
  };
216

  
217
  // Save the previous autocomplete prototype.
218
  var oldPrototype = Drupal.jsAC.prototype;
219

  
220
  /**
221
   * Override the autocomplete constructor.
222
   */
223
  Drupal.jsAC = function ($input, db, context) {
224
    var ac = this;
225

  
226
    // Context is normally passed by Drupal.behaviors.autocomplete above. However,
227
    // if a module has manually invoked this method they will likely not know
228
    // about this feature and a global fallback context to document must be used.
229
    // @see https://www.drupal.org/node/2594243
230
    // @see https://www.drupal.org/node/2315295
231
    this.$context = context && $(context) || $(document);
232

  
233
    this.input = $input[0];
234
    this.ariaLive = this.$context.find('#' + this.input.id + '-autocomplete-aria-live');
235
    this.db = db;
236
    $input
237
      .keydown(function (event) {
238
        return ac.onkeydown(this, event);
239
      })
240
      .keyup(function (event) {
241
        ac.onkeyup(this, event);
242
      })
243
      .blur(function () {
244
        ac.hidePopup();
245
        ac.db.cancel();
246
      });
247
  };
248

  
249
  // Restore the previous prototype.
250
  Drupal.jsAC.prototype = oldPrototype;
165 251

  
166 252
})(jQuery);

Formats disponibles : Unified diff