Projet

Général

Profil

Paste
Télécharger (4,58 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / themes / bootstrap / js / misc / autocomplete.js @ 4eeb3b46

1
(function ($) {
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);
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
  return $('.form-autocomplete > .dropdown').each(function () {
35
    this.owner.hidePopup();
36
  }).length == 0;
37
};
38

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

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

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

    
74
  // Do search.
75
  this.db.owner = this;
76
  this.db.search(this.input.value);
77
};
78

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

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

    
105
  // Show popup with matches, if any.
106
  if (this.popup) {
107
    if (ul.children().length) {
108
      $(this.popup).empty().append(ul).show();
109
      $(this.ariaLive).html(Drupal.t('Autocomplete popup'));
110
    }
111
    else {
112
      $(this.popup).css({ visibility: 'hidden' });
113
      this.hidePopup();
114
    }
115
  }
116
};
117

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

    
134
// Save the previous autocomplete prototype.
135
var oldPrototype = Drupal.jsAC.prototype;
136

    
137
/**
138
 * Override the autocomplete constructor.
139
 */
140
Drupal.jsAC = function ($input, db, context) {
141
  var ac = this;
142

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

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

    
159
// Restore the previous prototype.
160
Drupal.jsAC.prototype = oldPrototype;
161

    
162
})(jQuery);