Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gl_dropdown_filter.js « deprecated_jquery_dropdown « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 271347feebd9bf20f94a5e5aa37f64cbea89a67f (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
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import $ from 'jquery';
import { debounce } from 'lodash';
import { isObject } from '~/lib/utils/type_utility';

const BLUR_KEYCODES = [27, 40];

const HAS_VALUE_CLASS = 'has-value';

export class GitLabDropdownFilter {
  constructor(input, options) {
    let ref;
    this.input = input;
    this.options = options;
    // eslint-disable-next-line no-cond-assign
    this.filterInputBlur = (ref = this.options.filterInputBlur) != null ? ref : true;
    const $inputContainer = this.input.parent();
    const $clearButton = $inputContainer.find('.js-dropdown-input-clear');
    const filterRemoteDebounced = debounce(() => {
      options.instance.dropdown.trigger('filtering.gl.dropdown');
      $inputContainer.parent().addClass('is-loading');

      return this.options.query(this.input.val(), (data) => {
        options.instance.dropdown.trigger('done.filtering.gl.dropdown');
        $inputContainer.parent().removeClass('is-loading');
        return this.options.callback(data);
      });
    }, 500);

    $clearButton.on('click', (e) => {
      // Clear click
      e.preventDefault();
      e.stopPropagation();
      return this.input.val('').trigger('input').focus();
    });
    // Key events
    this.input
      .on('keydown', (e) => {
        const keyCode = e.which;
        if (keyCode === 13 && !options.elIsInput) {
          e.preventDefault();
        }
      })
      .on('input', () => {
        if (this.input.val() !== '' && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
          $inputContainer.addClass(HAS_VALUE_CLASS);
        } else if (this.input.val() === '' && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
          $inputContainer.removeClass(HAS_VALUE_CLASS);
        }
        // Only filter asynchronously only if option remote is set
        if (this.options.remote) {
          return filterRemoteDebounced();
        }
        return this.filter(this.input.val());
      });
  }

  static shouldBlur(keyCode) {
    return BLUR_KEYCODES.indexOf(keyCode) !== -1;
  }

  // eslint-disable-next-line consistent-return
  filter(searchText) {
    let group;
    let results;
    let tmp;
    if (this.options.onFilter) {
      this.options.onFilter(searchText);
    }
    const data = this.options.data();
    if (data != null && !this.options.filterByText) {
      results = data;
      if (searchText !== '') {
        // When data is an array of objects therefore [object Array] e.g.
        // [
        //   { prop: 'foo' },
        //   { prop: 'baz' }
        // ]
        if (Array.isArray(data)) {
          results = fuzzaldrinPlus.filter(data, searchText, {
            key: this.options.keys,
          });
        }
        // If data is grouped therefore an [object Object]. e.g.
        // {
        //   groupName1: [
        //     { prop: 'foo' },
        //     { prop: 'baz' }
        //   ],
        //   groupName2: [
        //     { prop: 'abc' },
        //     { prop: 'def' }
        //   ]
        // }
        else if (isObject(data)) {
          results = {};
          Object.keys(data).forEach((key) => {
            group = data[key];
            tmp = fuzzaldrinPlus.filter(group, searchText, {
              key: this.options.keys,
            });
            if (tmp.length) {
              results[key] = tmp.map((item) => item);
            }
          });
        }
      }
      return this.options.callback(results);
    }
    const elements = this.options.elements();
    if (searchText) {
      // eslint-disable-next-line func-names
      elements.each(function () {
        const $el = $(this);
        const matches = fuzzaldrinPlus.match($el.text().trim(), searchText);
        if (!$el.is('.dropdown-header')) {
          if (matches.length) {
            $el.show().removeClass('option-hidden');
          } else {
            $el.hide().addClass('option-hidden');
          }
        }
      });
    } else {
      elements.show().removeClass('option-hidden');
    }

    elements
      .parent()
      .find('.dropdown-menu-empty-item')
      .toggleClass('hidden', elements.is(':visible'));
  }
}