function GitLabDropdown()

in app/assets/javascripts/gl_dropdown.js [296:485]


  function GitLabDropdown(el1, options) {
    var searchFields, selector, self;
    this.el = el1;
    this.options = options;
    this.updateLabel = this.updateLabel.bind(this);
    this.hidden = this.hidden.bind(this);
    this.opened = this.opened.bind(this);
    this.shouldPropagate = this.shouldPropagate.bind(this);
    self = this;
    selector = $(this.el).data('target');
    this.dropdown = selector != null ? $(selector) : $(this.el).parent();
    // Set Defaults
    this.filterInput = this.options.filterInput || this.getElement(FILTER_INPUT);
    this.noFilterInput = this.options.noFilterInput || this.getElement(NO_FILTER_INPUT);
    this.highlight = Boolean(this.options.highlight);
    this.icon = Boolean(this.options.icon);
    this.filterInputBlur =
      this.options.filterInputBlur != null ? this.options.filterInputBlur : true;
    // If no input is passed create a default one
    self = this;
    // If selector was passed
    if (_.isString(this.filterInput)) {
      this.filterInput = this.getElement(this.filterInput);
    }
    searchFields = this.options.search ? this.options.search.fields : [];
    if (this.options.data) {
      // If we provided data
      // data could be an array of objects or a group of arrays
      if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) {
        this.fullData = this.options.data;
        currentIndex = -1;
        this.parseData(this.options.data);
        this.focusTextInput();
      } else {
        this.remote = new GitLabDropdownRemote(this.options.data, {
          dataType: this.options.dataType,
          beforeSend: this.toggleLoading.bind(this),
          success: (function(_this) {
            return function(data) {
              _this.fullData = data;
              _this.parseData(_this.fullData);
              _this.focusTextInput();

              // Update dropdown position since remote data may have changed dropdown size
              _this.dropdown.find('.dropdown-menu-toggle').dropdown('update');

              if (
                _this.options.filterable &&
                _this.filter &&
                _this.filter.input &&
                _this.filter.input.val() &&
                _this.filter.input.val().trim() !== ''
              ) {
                return _this.filter.input.trigger('input');
              }
            };
            // Remote data
          })(this),
          instance: this,
        });
      }
    }
    if (this.noFilterInput.length) {
      this.plainInput = new GitLabDropdownInput(this.noFilterInput, this.options);
      this.plainInput.onInput(this.addInput.bind(this));
    }
    // Init filterable
    if (this.options.filterable) {
      this.filter = new GitLabDropdownFilter(this.filterInput, {
        elIsInput: $(this.el).is('input'),
        filterInputBlur: this.filterInputBlur,
        filterByText: this.options.filterByText,
        onFilter: this.options.onFilter,
        remote: this.options.filterRemote,
        query: this.options.data,
        keys: searchFields,
        instance: this,
        elements: (function(_this) {
          return function() {
            selector = '.dropdown-content li:not(' + NON_SELECTABLE_CLASSES + ')';
            if (_this.dropdown.find('.dropdown-toggle-page').length) {
              selector = '.dropdown-page-one ' + selector;
            }
            return $(selector, this.instance.dropdown);
          };
        })(this),
        data: (function(_this) {
          return function() {
            return _this.fullData;
          };
        })(this),
        callback: (function(_this) {
          return function(data) {
            _this.parseData(data);
            if (_this.filterInput.val() !== '') {
              selector = SELECTABLE_CLASSES;
              if (_this.dropdown.find('.dropdown-toggle-page').length) {
                selector = '.dropdown-page-one ' + selector;
              }
              if ($(_this.el).is('input')) {
                currentIndex = -1;
              } else {
                $(selector, _this.dropdown)
                  .first()
                  .find('a')
                  .addClass('is-focused');
                currentIndex = 0;
              }
            }
          };
        })(this),
      });
    }
    // Event listeners
    this.dropdown.on('shown.bs.dropdown', this.opened);
    this.dropdown.on('hidden.bs.dropdown', this.hidden);
    $(this.el).on('update.label', this.updateLabel);
    this.dropdown.on('click', '.dropdown-menu, .dropdown-menu-close', this.shouldPropagate);
    this.dropdown.on(
      'keyup',
      (function(_this) {
        return function(e) {
          // Escape key
          if (e.which === 27) {
            return $('.dropdown-menu-close', _this.dropdown).trigger('click');
          }
        };
      })(this),
    );
    this.dropdown.on(
      'blur',
      'a',
      (function(_this) {
        return function(e) {
          var $dropdownMenu, $relatedTarget;
          if (e.relatedTarget != null) {
            $relatedTarget = $(e.relatedTarget);
            $dropdownMenu = $relatedTarget.closest('.dropdown-menu');
            if ($dropdownMenu.length === 0) {
              return _this.dropdown.removeClass('show');
            }
          }
        };
      })(this),
    );
    if (this.dropdown.find('.dropdown-toggle-page').length) {
      this.dropdown.find('.dropdown-toggle-page, .dropdown-menu-back').on(
        'click',
        (function(_this) {
          return function(e) {
            e.preventDefault();
            e.stopPropagation();
            return _this.togglePage();
          };
        })(this),
      );
    }
    if (this.options.selectable) {
      selector = '.dropdown-content a';
      if (this.dropdown.find('.dropdown-toggle-page').length) {
        selector = '.dropdown-page-one .dropdown-content a';
      }
      this.dropdown.on(
        'click',
        selector,
        function(e) {
          var $el, selected, selectedObj, isMarking;
          $el = $(e.currentTarget);
          selected = self.rowClicked($el);
          selectedObj = selected ? selected[0] : null;
          isMarking = selected ? selected[1] : null;
          if (this.options.clicked) {
            this.options.clicked.call(this, {
              selectedObj,
              $el,
              e,
              isMarking,
            });
          }

          // Update label right after all modifications in dropdown has been done
          if (this.options.toggleLabel) {
            this.updateLabel(selectedObj, $el, this);
          }

          $el.trigger('blur');
        }.bind(this),
      );
    }
  }