diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) | |
download | gitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz |
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js')
-rw-r--r-- | app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js b/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js new file mode 100644 index 00000000000..89ffb5f5f79 --- /dev/null +++ b/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown_filter.js @@ -0,0 +1,135 @@ +/* eslint-disable consistent-return */ + +import $ from 'jquery'; +import fuzzaldrinPlus from 'fuzzaldrin-plus'; +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; + let timeout; + 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'); + $clearButton.on('click', e => { + // Clear click + e.preventDefault(); + e.stopPropagation(); + return this.input + .val('') + .trigger('input') + .focus(); + }); + // Key events + timeout = ''; + 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) { + clearTimeout(timeout); + // eslint-disable-next-line no-return-assign + return (timeout = setTimeout(() => { + $inputContainer.parent().addClass('is-loading'); + + return this.options.query(this.input.val(), data => { + $inputContainer.parent().removeClass('is-loading'); + return this.options.callback(data); + }); + }, 250)); + } + return this.filter(this.input.val()); + }); + } + + static shouldBlur(keyCode) { + return BLUR_KEYCODES.indexOf(keyCode) !== -1; + } + + 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) { + return $el.show().removeClass('option-hidden'); + } + return $el.hide().addClass('option-hidden'); + } + }); + } else { + elements.show().removeClass('option-hidden'); + } + + elements + .parent() + .find('.dropdown-menu-empty-item') + .toggleClass('hidden', elements.is(':visible')); + } +} |