Projet

Général

Profil

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

root / drupal7 / sites / all / themes / bootstrap / js / misc / autocomplete.js @ 7547bb19

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
  $('.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.
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'));
114
    }
115
    else {
116
      $(this.popup).css({ visibility: 'hidden' });
117
      this.hidePopup();
118
    }
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;
165

    
166
})(jQuery);