diff options
author | Alfredo Sumaran <alfredo@gitlab.com> | 2016-03-08 02:56:43 -0500 |
---|---|---|
committer | Alfredo Sumaran <alfredo@gitlab.com> | 2016-03-08 02:56:43 -0500 |
commit | 13fee27f32482736a874740939d2e80e3bb7d0ee (patch) | |
tree | 98e93e85db7edf412b05ab138d0d3a4f5bd322c7 /app/assets/javascripts/search_autocomplete.js.coffee | |
parent | 903aa7c95e82949ca0a7b18e1f6d2f25fe1b04f4 (diff) | |
download | gitlab-ce-wip_issue_3400.tar.gz |
Working version of autocomplete with categorized resultswip_issue_3400
Diffstat (limited to 'app/assets/javascripts/search_autocomplete.js.coffee')
-rw-r--r-- | app/assets/javascripts/search_autocomplete.js.coffee | 169 |
1 files changed, 161 insertions, 8 deletions
diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee index c1801365266..df31b07910c 100644 --- a/app/assets/javascripts/search_autocomplete.js.coffee +++ b/app/assets/javascripts/search_autocomplete.js.coffee @@ -1,11 +1,164 @@ class @SearchAutocomplete - constructor: (search_autocomplete_path, project_id, project_ref) -> - project_id = '' unless project_id - project_ref = '' unless project_ref - query = "?project_id=" + project_id + "&project_ref=" + project_ref + constructor: (opts = {}) -> + { + @wrap = $('.search') + @optsEl = @wrap.find('.search-autocomplete-opts') + @autocompletePath = @optsEl.data('autocomplete-path') + @projectId = @optsEl.data('autocomplete-project-id') || '' + @projectRef = @optsEl.data('autocomplete-project-ref') || '' + } = opts - $("#search").autocomplete - source: search_autocomplete_path + query + @keyCode = + ESCAPE: 27 + BACKSPACE: 8 + TAB: 9 + ENTER: 13 + + @locationBadgeEl = @$('.search-location-badge') + @locationText = @$('.location-text') + @searchInput = @$('.search-input') + @projectInputEl = @$('#project_id') + @groupInputEl = @$('#group_id') + @searchCodeInputEl = @$('#search_code') + @repositoryInputEl = @$('#repository_ref') + @scopeInputEl = @$('#scope') + + @saveOriginalState() + @createAutocomplete() + @bindEvents() + + $: (selector) -> + @wrap.find(selector) + + saveOriginalState: -> + @originalState = @serializeState() + + restoreOriginalState: -> + inputs = Object.keys @originalState + + for input in inputs + @$("##{input}").val(@originalState[input]) + + + if @originalState._location is '' + @locationBadgeEl.html('') + else + @addLocationBadge( + value: @originalState._location + ) + + serializeState: -> + { + # Search Criteria + project_id: @projectInputEl.val() + group_id: @groupInputEl.val() + search_code: @searchCodeInputEl.val() + repository_ref: @repositoryInputEl.val() + + # Location badge + _location: $.trim(@locationText.text()) + } + + createAutocomplete: -> + @query = "?project_id=" + @projectId + "&project_ref=" + @projectRef + + @catComplete = @searchInput.catcomplete + appendTo: 'form.navbar-form' + source: @autocompletePath + @query minLength: 1 - select: (event, ui) -> - location.href = ui.item.url + close: (e) -> + e.preventDefault() + + select: (event, ui) => + # Pressing enter choses an alternative + if event.keyCode is @keyCode.ENTER + @goToResult(ui.item) + else + # Pressing tab sets the scope + if event.keyCode is @keyCode.TAB and ui.item.scope? + @setLocationBadge(ui.item) + @searchInput + .val('') # remove selected value from input + .focus() + else + # If option is not a scope go to page + @goToResult(ui.item) + + # Return false to avoid focus on the next element + return false + + + bindEvents: -> + @searchInput.on 'keydown', @onSearchKeyDown + @wrap.on 'click', '.remove-badge', @onRemoveLocationBadgeClick + + onRemoveLocationBadgeClick: (e) => + e.preventDefault() + @removeLocationBadge() + @searchInput.focus() + + onSearchKeyDown: (e) => + # Remove tag when pressing backspace and input search is empty + if e.keyCode is @keyCode.BACKSPACE and e.currentTarget.value is '' + @removeLocationBadge() + @destroyAutocomplete() + @searchInput.focus() + else if e.keyCode is @keyCode.ESCAPE + @restoreOriginalState() + else + # Create new autocomplete instance if it's not created + @createAutocomplete() unless @catcomplete? + + addLocationBadge: (item) -> + category = if item.category? then "#{item.category}: " else '' + value = if item.value? then item.value else '' + + html = "<span class='label label-primary'> + <i class='location-text'>#{category}#{value}</i> + <a class='remove-badge' href='#'>x</a> + </span>" + @locationBadgeEl.html(html) + + setLocationBadge: (item) -> + @addLocationBadge(item) + + # Reset input states + @resetSearchState() + + switch item.scope + when 'projects' + @projectInputEl.val(item.id) + # @searchCodeInputEl.val('true') # TODO: always true for projects? + # @repositoryInputEl.val('master') # TODO: always master? + + when 'groups' + @groupInputEl.val(item.id) + + removeLocationBadge: -> + @locationBadgeEl.empty() + + # Reset state + @resetSearchState() + + resetSearchState: -> + # Remove scope + @scopeInputEl.val('') + + # Remove group + @groupInputEl.val('') + + # Remove project id + @projectInputEl.val('') + + # Remove code search + @searchCodeInputEl.val('') + + # Remove repository ref + @repositoryInputEl.val('') + + goToResult: (result) -> + location.href = result.url + + destroyAutocomplete: -> + @catComplete.destroy() if @catcomplete? + @catComplete = null |