diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/gl_dropdown.js | 74 | ||||
-rw-r--r-- | app/assets/javascripts/search_autocomplete.js | 18 |
2 files changed, 57 insertions, 35 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index d3394fae3f9..f85aa6dd7b7 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -31,9 +31,8 @@ this.input .on('keydown', function (e) { var keyCode = e.which; - if (keyCode === 13) { - e.preventDefault() + e.preventDefault(); } }) .on('keyup', function(e) { @@ -111,9 +110,9 @@ matches = fuzzaldrinPlus.match($el.text().trim(), search_text); if (!$el.is('.dropdown-header')) { if (matches.length) { - return $el.show(); + return $el.show().removeClass('option-hidden'); } else { - return $el.hide(); + return $el.hide().addClass('option-hidden'); } } }); @@ -179,7 +178,7 @@ })(); GitLabDropdown = (function() { - var ACTIVE_CLASS, FILTER_INPUT, INDETERMINATE_CLASS, LOADING_CLASS, PAGE_TWO_CLASS, currentIndex; + var ACTIVE_CLASS, FILTER_INPUT, INDETERMINATE_CLASS, LOADING_CLASS, PAGE_TWO_CLASS, NON_SELECTABLE_CLASSES, SELECTABLE_CLASSES, currentIndex; LOADING_CLASS = "is-loading"; @@ -191,6 +190,12 @@ currentIndex = -1; + NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-link, .option-hidden'; + + SELECTABLE_CLASSES = ".dropdown-content li:not(" + NON_SELECTABLE_CLASSES + ")"; + + CURSOR_SELECT_SCROLL_PADDING = 5 + FILTER_INPUT = '.dropdown-input .dropdown-input-field'; function GitLabDropdown(el1, options) { @@ -213,6 +218,7 @@ if (this.options.data) { if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) { this.fullData = this.options.data; + currentIndex = -1; this.parseData(this.options.data); } else { this.remote = new GitLabDropdownRemote(this.options.data, { @@ -240,7 +246,7 @@ keys: searchFields, elements: (function(_this) { return function() { - selector = '.dropdown-content li:not(.divider)'; + selector = '.dropdown-content li:not(' + NON_SELECTABLE_CLASSES + ')'; if (_this.dropdown.find('.dropdown-toggle-page').length) { selector = ".dropdown-page-one " + selector; } @@ -256,7 +262,7 @@ return function(data) { _this.parseData(data); if (_this.filterInput.val() !== '') { - selector = '.dropdown-content li:not(.divider):visible'; + selector = SELECTABLE_CLASSES; if (_this.dropdown.find('.dropdown-toggle-page').length) { selector = ".dropdown-page-one " + selector; } @@ -376,7 +382,7 @@ var $target; if (this.options.multiSelect) { $target = $(e.target); - if (!$target.hasClass('dropdown-menu-close') && !$target.hasClass('dropdown-menu-close-icon') && !$target.data('is-link')) { + if ($target && !$target.hasClass('dropdown-menu-close') && !$target.hasClass('dropdown-menu-close-icon') && !$target.data('is-link')) { e.stopPropagation(); return false; } else { @@ -387,7 +393,7 @@ GitLabDropdown.prototype.opened = function() { var contentHtml; - currentIndex = -1; + this.resetRows(); this.addArrowKeyEvent(); if (this.options.setIndeterminateIds) { this.options.setIndeterminateIds.call(this); @@ -410,6 +416,7 @@ GitLabDropdown.prototype.hidden = function(e) { var $input; + this.resetRows(); this.removeArrayKeyEvent(); $input = this.dropdown.find(".dropdown-input-field"); if (this.options.filterable) { @@ -463,7 +470,7 @@ return "<li class='separator'></li>"; } if (data.header != null) { - return "<li class='dropdown-header'>" + data.header + "</li>"; + return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header }); } if (this.options.renderRow) { html = this.options.renderRow.call(this.options, data, this); @@ -494,11 +501,16 @@ text = this.highlightTextMatches(text, this.filterInput.val()); } if (group) { - groupAttrs = "data-group='" + group + "' data-index='" + index + "'"; + groupAttrs = 'data-group=' + group + ' data-index=' + index; } else { groupAttrs = ''; } - html = "<li> <a href='" + url + "' " + groupAttrs + " class='" + cssClass + "'> " + text + " </a> </li>"; + html = _.template('<li><a href="<%- url %>" <%- groupAttrs %> class="<%- cssClass %>"><%= text %></a></li>')({ + url: url, + groupAttrs: groupAttrs, + cssClass: cssClass, + text: text + }); } return html; }; @@ -520,17 +532,6 @@ return html = "<li class='dropdown-menu-empty-link'> <a href='#' class='is-focused'> No matching results. </a> </li>"; }; - GitLabDropdown.prototype.highlightRow = function(index) { - var selector; - if (this.filterInput.val() !== "") { - selector = '.dropdown-content li:first-child a'; - if (this.dropdown.find(".dropdown-toggle-page").length) { - selector = ".dropdown-page-one .dropdown-content li:first-child a"; - } - return this.getElement(selector).addClass('is-focused'); - } - }; - GitLabDropdown.prototype.rowClicked = function(el) { var field, fieldName, groupName, isInput, selectedIndex, selectedObject, value; fieldName = this.options.fieldName; @@ -609,13 +610,15 @@ GitLabDropdown.prototype.selectRowAtIndex = function(index) { var $el, selector; - selector = ".dropdown-content li:not(.divider,.dropdown-header,.separator):eq(" + index + ") a"; + selector = SELECTABLE_CLASSES + ":eq(" + index + ") a"; if (this.dropdown.find(".dropdown-toggle-page").length) { selector = ".dropdown-page-one " + selector; } $el = $(selector, this.dropdown); if ($el.length) { - return $el.first().trigger('click'); + $el.first().trigger('click'); + var href = $el.attr('href'); + if (href && href !== '#') Turbolinks.visit(href); } }; @@ -623,7 +626,7 @@ var $input, ARROW_KEY_CODES, selector; ARROW_KEY_CODES = [38, 40]; $input = this.dropdown.find(".dropdown-input-field"); - selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator):visible'; + selector = SELECTABLE_CLASSES; if (this.dropdown.find(".dropdown-toggle-page").length) { selector = ".dropdown-page-one " + selector; } @@ -651,7 +654,7 @@ return false; } if (currentKeyCode === 13 && currentIndex !== -1) { - return _this.selectRowAtIndex($('.is-focused', _this.dropdown).closest('li').index() - 1); + return _this.selectRowAtIndex(currentIndex); } }; })(this)); @@ -661,6 +664,11 @@ return $('body').off('keydown'); }; + GitLabDropdown.prototype.resetRows = function resetRows() { + currentIndex = -1; + $('.is-focused', this.dropdown).removeClass('is-focused'); + }; + GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) { var $dropdownContent, $listItem, dropdownContentBottom, dropdownContentHeight, dropdownContentTop, dropdownScrollTop, listItemBottom, listItemHeight, listItemTop; $('.is-focused', this.dropdown).removeClass('is-focused'); @@ -674,10 +682,14 @@ listItemHeight = $listItem.outerHeight(); listItemTop = $listItem.prop('offsetTop'); listItemBottom = listItemTop + listItemHeight; - if (listItemBottom > dropdownContentBottom + dropdownScrollTop) { - return $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom); - } else if (listItemTop < dropdownContentTop + dropdownScrollTop) { - return $dropdownContent.scrollTop(listItemTop - dropdownContentTop); + if (!index) { + $dropdownContent.scrollTop(0) + } else if (index === ($listItems.length - 1)) { + $dropdownContent.scrollTop($dropdownContent.prop('scrollHeight')); + } else if (listItemBottom > (dropdownContentBottom + dropdownScrollTop)) { + $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom + CURSOR_SELECT_SCROLL_PADDING); + } else if (listItemTop < (dropdownContentTop + dropdownScrollTop)) { + return $dropdownContent.scrollTop(listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING); } }; diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js index 990f6536eb2..227e8c696b4 100644 --- a/app/assets/javascripts/search_autocomplete.js +++ b/app/assets/javascripts/search_autocomplete.js @@ -7,7 +7,9 @@ KEYCODE = { ESCAPE: 27, BACKSPACE: 8, - ENTER: 13 + ENTER: 13, + UP: 38, + DOWN: 40 }; function SearchAutocomplete(opts) { @@ -223,6 +225,12 @@ case KEYCODE.ESCAPE: this.restoreOriginalState(); break; + case KEYCODE.ENTER: + this.disableAutocomplete(); + break; + case KEYCODE.UP: + case KEYCODE.DOWN: + return; default: if (this.searchInput.val() === '') { this.disableAutocomplete(); @@ -319,9 +327,11 @@ }; SearchAutocomplete.prototype.disableAutocomplete = function() { - this.searchInput.addClass('disabled'); - this.dropdown.removeClass('open'); - return this.restoreMenu(); + if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('open')) { + this.searchInput.addClass('disabled'); + this.dropdown.removeClass('open').trigger('hidden.bs.dropdown'); + this.restoreMenu(); + } }; SearchAutocomplete.prototype.restoreMenu = function() { |