summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/search_autocomplete.js.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/search_autocomplete.js.coffee')
-rw-r--r--app/assets/javascripts/search_autocomplete.js.coffee169
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