aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server/src/main/js/top-search.js
blob: 4f4cc946347f6e20c0265d06281e5c59cc4b8051 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
(function($) {

  $.fn.topSearch = function(options) {

    var el = $(this),
        resultsEl = $(options.results),
        spinnerEl = $(options.spinner);

    var index, total, selected, items, term, symbol = false;


    var select = function() {
          if (selected) {
            selected.removeClass('selected');
          }

          selected = items.eq(index);
          selected.addClass('selected');
        },

        selectPrev = function() {
          if (index > 0) {
            index--;
          }
          select();
        },

        selectNext = function() {
           if (index < total - 1) {
             index++;
           }
          select();
        },

        choose = function() {
          if (selected) {
            var key = selected.data('key');
            window.location = baseUrl + '/dashboard/index/' + key + dashboardParameters();
          }
        },

        show = function(r) {
          resultsEl.empty();

          var ul = $('<ul></ul>').appendTo(resultsEl);

          r.results.forEach(function(qualifier) {
            qualifier.items.forEach(function(item, index) {
              var el = $('<li></li>')
                  .data('key', item.id),

                  q = $('<div></div>')
                      .addClass('q')
                      .appendTo(el),

                  highlightRegexp = new RegExp(term, 'gi'),
                  highlightedName = item.name.replace(highlightRegexp, '<strong>$&</strong>'),

                  label = $('<span></span>')
                      .html(' ' + highlightedName)
                      .appendTo(el);

              $('<i>')
                  .addClass('icon-qualifier-' + qualifier.q.toLowerCase())
                  .prependTo(label);

              if (index === 0) {
                q.text(qualifier.name);
              }

              el.appendTo(ul);
            });
          });

          resultsEl.append('<div class="autocompleteNote">' + r.total + ' ' + resultsEl.data('results') + '</div>');

          resultsEl.show();

          if (r.total === 0) {
            ul.append('<li>' + resultsEl.data('no-results') + '</li>');
          } else {
            items = resultsEl.find('li');
            index = -1;
            total = items.length;
            selectNext();

            items
                .on('mouseover', function() {
                  index = items.index($(this));
                  select();
                })
                .on('click', function() {
                  index = items.index($(this));
                  select();
                  choose();
                });
          }
        },

        hide = function() {
          resultsEl.fadeOut();
        },

        onKeyup = function() {
          if (symbol) {
            if (el.val().length >= options.minLength) {
              term = el.val();

              spinnerEl.show();
              $.ajax({
                url: baseUrl + '/api/components/suggestions',
                data: { s: term }
              })
                  .done(function(r) {
                    show(r);
                  })
                  .fail(hide)
                  .always(function() {
                    spinnerEl.hide();
                  });
            } else {
              hide();
            }
          }
        },

        debouncedKeyup = _.debounce(onKeyup, 250),

        onKeyDown = function(e) {
          if ([13, 38, 40, 37, 39, 16, 17, 18, 91, 20, 21].indexOf(e.keyCode) !== -1) {
            symbol = false;
          }

          switch (e.keyCode) {
            case 13: // return
              e.preventDefault();
              choose();
              return;
            case 38: // up
              e.preventDefault();
              selectPrev();
              return;
            case 40: // down
              e.preventDefault();
              selectNext();
              return;
            default:
              symbol = true;
          }
        };


    el
        .on('keydown', onKeyDown)
        .on('keyup', debouncedKeyup)
        .on('focus', function() {
          el.data('placeholder', el.val());
          el.val('');
        })
        .on('focusout', function() {
          if (el.val().length === 0) {
            el.val(el.data('placeholder') || '');
          }
          hide();
        });

    $('body').on('mousedown', function() {
      hide();
    });
  };

})(jQuery);