Commit affdf201 authored by Luke "Jared" Bennett's avatar Luke "Jared" Bennett Committed by Luke Bennett

Further review changes and removed large ammounts of reformatting

parent 1ac5f764
class GitLabDropdownFilter
BLUR_KEYCODES = [27, 40]
ARROW_KEY_CODES = [38, 40]
HAS_VALUE_CLASS = 'has-value'
HAS_VALUE_CLASS = "has-value"
constructor: (@input, @options) ->
{
......@@ -9,7 +9,7 @@ class GitLabDropdownFilter
} = @options
$inputContainer = @input.parent()
$clearButton = $inputContainer.find '.js-dropdown-input-clear'
$clearButton = $inputContainer.find('.js-dropdown-input-clear')
@indeterminateIds = []
......@@ -18,23 +18,24 @@ class GitLabDropdownFilter
e.preventDefault()
e.stopPropagation()
@input
.val ''
.trigger 'keyup'
.val('')
.trigger('keyup')
.focus()
# Key events
timeout = ''
@input.on 'keyup', (e) =>
timeout = ""
@input.on "keyup", (e) =>
keyCode = e.which
return if ARROW_KEY_CODES.indexOf(keyCode) >= 0
if @input.val() isnt '' and not $inputContainer.hasClass HAS_VALUE_CLASS
if @input.val() isnt "" and !$inputContainer.hasClass HAS_VALUE_CLASS
$inputContainer.addClass HAS_VALUE_CLASS
else if @input.val() is '' and $inputContainer.hasClass HAS_VALUE_CLASS
else if @input.val() is "" and $inputContainer.hasClass HAS_VALUE_CLASS
$inputContainer.removeClass HAS_VALUE_CLASS
return false if keyCode is 13
if keyCode is 13
return false
# Only filter asynchronously only if option remote is set
if @options.remote
......@@ -46,13 +47,13 @@ class GitLabDropdownFilter
@input.blur()
@options.query @input.val(), (data) =>
@options.callback data
@options.callback(data)
, 250
else
@filter @input.val()
shouldBlur: (keyCode) ->
BLUR_KEYCODES.indexOf(keyCode) >= 0
return BLUR_KEYCODES.indexOf(keyCode) >= 0
filter: (search_text) ->
@options.onFilter(search_text) if @options.onFilter
......@@ -68,8 +69,9 @@ class GitLabDropdownFilter
# { prop: 'baz' }
# ]
if _.isArray(data)
results = fuzzaldrinPlus.filter data, search_text,
results = fuzzaldrinPlus.filter(data, search_text,
key: @options.keys
)
else
# If data is grouped therefore an [object Object]. e.g.
# {
......@@ -85,8 +87,9 @@ class GitLabDropdownFilter
if gl.utils.isObject data
results = {}
for key, group of data
tmp = fuzzaldrinPlus.filter group, search_text,
tmp = fuzzaldrinPlus.filter(group, search_text,
key: @options.keys
)
if tmp.length
results[key] = tmp.map (item) -> item
......@@ -97,10 +100,10 @@ class GitLabDropdownFilter
if search_text
elements.each ->
$el = $(this)
matches = fuzzaldrinPlus.match $el.text().trim(), search_text
$el = $(@)
matches = fuzzaldrinPlus.match($el.text().trim(), search_text)
unless $el.is '.dropdown-header'
unless $el.is('.dropdown-header')
if matches.length
$el.show()
else
......@@ -112,68 +115,75 @@ class GitLabDropdownRemote
constructor: (@dataEndpoint, @options) ->
execute: ->
if typeof @dataEndpoint is 'string'
if typeof @dataEndpoint is "string"
@fetchData()
else if typeof @dataEndpoint is 'function'
@options.beforeSend() if @options.beforeSend
else if typeof @dataEndpoint is "function"
if @options.beforeSend
@options.beforeSend()
# Fetch the data by calling the data funcfion
@dataEndpoint '', (data) =>
@options.success(data) if @options.success
@options.beforeSend() if @options.beforeSend
@dataEndpoint "", (data) =>
if @options.success
@options.success(data)
if @options.beforeSend
@options.beforeSend()
# Fetch the data through ajax if the data is a string
fetchData: ->
$.ajax
$.ajax(
url: @dataEndpoint,
dataType: @options.dataType,
beforeSend: =>
@options.beforeSend() if @options.beforeSend
if @options.beforeSend
@options.beforeSend()
success: (data) =>
@options.success(data) if @options.success
if @options.success
@options.success(data)
)
class GitLabDropdown
LOADING_CLASS = 'is-loading'
PAGE_TWO_CLASS = 'is-page-two'
ACTIVE_CLASS = 'is-active'
INDETERMINATE_CLASS = 'is-indeterminate'
LOADING_CLASS = "is-loading"
PAGE_TWO_CLASS = "is-page-two"
ACTIVE_CLASS = "is-active"
INDETERMINATE_CLASS = "is-indeterminate"
currentIndex = -1
NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-link'
SELECTABLE_CLASSES = ".dropdown-content li:not(#{NON_SELECTABLE_CLASSES})"
FILTER_INPUT = '.dropdown-input .dropdown-input-field'
currentIndex = -1
CURSOR_SELECT_SCROLL_PADDING = 5
constructor: (@el, @options) ->
self = this
selector = $(@el).data 'target'
self = @
selector = $(@el).data "target"
@dropdown = if selector? then $(selector) else $(@el).parent()
# Set Defaults
{
# If no input is passed create a default one
@filterInput = @getElement FILTER_INPUT
@filterInput = @getElement(FILTER_INPUT)
@highlight = false
@filterInputBlur = true
} = @options
self = this
self = @
# If selector was passed
@filterInput = @getElement(@filterInput) if _.isString @filterInput
if _.isString(@filterInput)
@filterInput = @getElement(@filterInput)
searchFields = if @options.search then @options.search.fields else []
if @options.data
# If we provided data
# data could be an array of objects or a group of arrays
if _.isObject(@options.data) and not _.isFunction @options.data
if _.isObject(@options.data) and not _.isFunction(@options.data)
@fullData = @options.data
@parseData @options.data
else
# Remote data
@remote = new GitLabDropdownRemote @options.data,
@remote = new GitLabDropdownRemote @options.data, {
dataType: @options.dataType,
beforeSend: @toggleLoading.bind this
beforeSend: @toggleLoading.bind(@)
success: (data) =>
@fullData = data
......@@ -181,8 +191,8 @@ class GitLabDropdown
currentIndex = -1
@parseData @fullData
if @options.filterable and @filter and @filter.input
@filter.input.trigger 'keyup'
@filter.input.trigger('keyup') if @options.filterable and @filter and @filter.input
}
# Init filterable
if @options.filterable
......@@ -199,9 +209,9 @@ class GitLabDropdown
if @dropdown.find('.dropdown-toggle-page').length
selector = ".dropdown-page-one #{selector}"
$(selector)
return $(selector)
data: =>
@fullData
return @fullData
callback: (data) =>
@parseData data
......@@ -221,35 +231,37 @@ class GitLabDropdown
# Event listeners
@dropdown.on 'shown.bs.dropdown', @opened
@dropdown.on 'hidden.bs.dropdown', @hidden
$(@el).on 'update.label', @updateLabel
@dropdown.on 'click', '.dropdown-menu, .dropdown-menu-close', @shouldPropagate
@dropdown.on "shown.bs.dropdown", @opened
@dropdown.on "hidden.bs.dropdown", @hidden
$(@el).on "update.label", @updateLabel
@dropdown.on "click", ".dropdown-menu, .dropdown-menu-close", @shouldPropagate
@dropdown.on 'keyup', (e) =>
$('.dropdown-menu-close', @dropdown).trigger 'click' if e.which is 27
if e.which is 27 # Escape key
$('.dropdown-menu-close', @dropdown).trigger 'click'
@dropdown.on 'blur', 'a', (e) =>
if e.relatedTarget?
$relatedTarget = $(e.relatedTarget)
$dropdownMenu = $relatedTarget.closest('.dropdown-menu')
@dropdown.removeClass('open') if $dropdownMenu.length is 0
if $dropdownMenu.length is 0
@dropdown.removeClass('open')
if @dropdown.find('.dropdown-toggle-page').length
@dropdown.find('.dropdown-toggle-page, .dropdown-menu-back').on 'click', (e) =>
if @dropdown.find(".dropdown-toggle-page").length
@dropdown.find(".dropdown-toggle-page, .dropdown-menu-back").on "click", (e) =>
e.preventDefault()
e.stopPropagation()
@togglePage()
if @options.selectable
selector = '.dropdown-content a'
selector = ".dropdown-content a"
if @dropdown.find('.dropdown-toggle-page').length
selector = '.dropdown-page-one .dropdown-content a'
if @dropdown.find(".dropdown-toggle-page").length
selector = ".dropdown-page-one .dropdown-content a"
@dropdown.on 'click', selector, (e) ->
$el = $(this)
@dropdown.on "click", selector, (e) ->
$el = $(@)
selected = self.rowClicked $el
if self.options.clicked
......@@ -268,7 +280,8 @@ class GitLabDropdown
menu = $('.dropdown-menu', @dropdown)
if menu.hasClass(PAGE_TWO_CLASS)
@remote.execute() if @remote
if @remote
@remote.execute()
menu.toggleClass PAGE_TWO_CLASS
......@@ -303,32 +316,38 @@ class GitLabDropdown
renderData: (data, group = false) ->
data.map (obj, index) =>
@renderItem(obj, group, index)
return @renderItem(obj, group, index)
shouldPropagate: (e) =>
$target = $(e.target) if @options.multiSelect
if @options.multiSelect
$target = $(e.target)
if $target and not $target.hasClass('dropdown-menu-close') and not $target.hasClass('dropdown-menu-close-icon') and not $target.data('is-link')
e.stopPropagation()
false
return false
else
true
return true
opened: =>
@resetRows()
@addArrowKeyEvent()
@options.setIndeterminateIds.call this if @options.setIndeterminateIds
if @options.setIndeterminateIds
@options.setIndeterminateIds.call(@)
@options.setActiveIds.call this if @options.setActiveIds
if @options.setActiveIds
@options.setActiveIds.call(@)
# Makes indeterminate items effective
if @fullData and @dropdown.find('.dropdown-menu-toggle').hasClass('js-filter-bulk-update')
@parseData @fullData
contentHtml = $('.dropdown-content', @dropdown).html()
@remote.execute() if @remote and contentHtml is ''
if @remote && contentHtml is ""
@remote.execute()
@filterInput.focus() if @options.filterable
if @options.filterable
@filterInput.focus()
@dropdown.trigger('shown.gl.dropdown')
......@@ -336,48 +355,51 @@ class GitLabDropdown
@resetRows()
@removeArrayKeyEvent()
$input = @dropdown.find('.dropdown-input-field')
$input = @dropdown.find(".dropdown-input-field")
if @options.filterable
$input
.blur()
.val('')
.val("")
# Triggering 'keyup' will re-render the dropdown which is not always required
# specially if we want to keep the state of the dropdown needed for bulk-assignment
$input.trigger('keyup') unless @options.persistWhenHide
if not @options.persistWhenHide
$input.trigger("keyup")
if @dropdown.find('.dropdown-toggle-page').length
if @dropdown.find(".dropdown-toggle-page").length
$('.dropdown-menu', @dropdown).removeClass PAGE_TWO_CLASS
@options.hidden.call this, e if @options.hidden
if @options.hidden
@options.hidden.call(@,e)
@dropdown.trigger('hidden.gl.dropdown')
# Render the full menu
renderMenu: (html) ->
menu_html = ''
menu_html = ""
if @options.renderMenu
menu_html = @options.renderMenu html
menu_html = @options.renderMenu(html)
else
menu_html = $('<ul/>').append html
menu_html = $('<ul />')
.append(html)
menu_html
return menu_html
# Append the menu into the dropdown
appendMenu: (html) ->
selector = '.dropdown-content'
if @dropdown.find('.dropdown-toggle-page').length
selector = '.dropdown-page-one .dropdown-content'
if @dropdown.find(".dropdown-toggle-page").length
selector = ".dropdown-page-one .dropdown-content"
$(selector, @dropdown)
.empty()
.append html
.append(html)
# Render the row
renderItem: (data, group = false, index = false) ->
html = ''
html = ""
# Divider
return '<li class="divider"></li>' if data is 'divider'
......@@ -392,11 +414,12 @@ class GitLabDropdown
# Call the render function
html = @options.renderRow.call(@options, data, @)
else
unless selected
if not selected
value = if @options.id then @options.id(data) else data.id
fieldName = @options.fieldName
field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']")
selected = true if field.length
if field.length
selected = true
# Set URL
if @options.url?
......@@ -410,15 +433,16 @@ class GitLabDropdown
else
text = if data.text? then data.text else ''
cssClass = ''
cssClass = ""
cssClass = 'is-active' if selected
if selected
cssClass = "is-active"
if @highlight
text = @highlightTextMatches(text, @filterInput.val())
if group
groupAttrs = "data-group=#{group} data-index=#{index}"
groupAttrs = "data-group='#{group}' data-index='#{index}'"
else
groupAttrs = ''
html = _.template('<li>
......@@ -432,7 +456,7 @@ class GitLabDropdown
text: text
})
html
return html
highlightTextMatches: (text, term) ->
occurrences = fuzzaldrinPlus.match(text, term)
......@@ -452,9 +476,9 @@ class GitLabDropdown
isInput = $(@el).is('input')
if @renderedData
groupName = el.data 'group'
groupName = el.data('group')
if groupName
selectedIndex = el.data 'index'
selectedIndex = el.data('index')
selectedObject = @renderedData[groupName][selectedIndex]
else
selectedIndex = el.closest('li').index()
......@@ -477,19 +501,20 @@ class GitLabDropdown
# Toggle the dropdown label
if @options.toggleLabel
@updateLabel(selectedObject, el, this)
@updateLabel(selectedObject, el, @)
else
selectedObject
else if el.hasClass(INDETERMINATE_CLASS)
el.addClass ACTIVE_CLASS
el.removeClass INDETERMINATE_CLASS
field.remove() unless value?
if not value?
field.remove()
if not field.length and fieldName
@addInput(fieldName, value)
selectedObject
return selectedObject
else
if not @options.multiSelect or el.hasClass('dropdown-clear-active')
@dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS
......@@ -497,29 +522,30 @@ class GitLabDropdown
unless isInput
@dropdown.parent().find("input[name='#{fieldName}']").remove()
field.remove() unless value?
if !value?
field.remove()
# Toggle active class for the tick mark
el.addClass ACTIVE_CLASS
# Toggle the dropdown label
if @options.toggleLabel
@updateLabel(selectedObject, el, this)
@updateLabel(selectedObject, el, @)
if value?
if not field.length and fieldName
if !field.length and fieldName
@addInput(fieldName, value)
else
field
.val value
.trigger 'change'
selectedObject
return selectedObject
addInput: (fieldName, value)->
# Create hidden input for form
$input = $('<input>').attr('type', 'hidden')
.attr('name', fieldName)
.val(value)
.attr('name', fieldName)
.val(value)
if @options.inputId?
$input.attr('id', @options.inputId)
......@@ -530,21 +556,22 @@ class GitLabDropdown
# Dropdown list item link selector, excluding non-selectable list items
selector = "#{SELECTABLE_CLASSES}:eq(#{index}) a"
if @dropdown.find('.dropdown-toggle-page').length
if @dropdown.find(".dropdown-toggle-page").length
selector = ".dropdown-page-one #{selector}"
# simulate a click on the first link
$el = $(selector, @dropdown)
if $el.length
e.preventDefault()
e.stopImmediatePropagation()
$el.first().trigger 'click'
$el.first().trigger('click')
href = $el.attr 'href'
Turbolinks.visit(href) if href and href isnt '#'
addArrowKeyEvent: ->
ARROW_KEY_CODES = [38, 40]
$input = @dropdown.find '.dropdown-input-field'
$input = @dropdown.find(".dropdown-input-field")
# Dropdown list item selector, excluding non-selectable list items
selector = SELECTABLE_CLASSES
......@@ -571,8 +598,7 @@ class GitLabDropdown
# Move up
currentIndex -= 1 if currentIndex > 0
if currentIndex isnt PREV_INDEX
@highlightRowAtIndex($listItems, currentIndex)
@highlightRowAtIndex($listItems, currentIndex) if currentIndex isnt PREV_INDEX
return false
......@@ -596,7 +622,7 @@ class GitLabDropdown
# Update the class for the row at the specific index
$listItem = $listItems.eq(index)
$listItem.find('a:first-child').addClass 'is-focused'
$listItem.find('a:first-child').addClass "is-focused"
# Dropdown content scroll area
$dropdownContent = $listItem.closest('.dropdown-content')
......@@ -624,9 +650,9 @@ class GitLabDropdown
$dropdownContent.scrollTop(listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING)
updateLabel: (selected = null, el = null, instance = null) =>
$(@el).find('.dropdown-toggle-text').text @options.toggleLabel(selected, el, instance)
$(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selected, el, instance)
$.fn.glDropdown = (opts) ->
@each ->
unless $.data this, 'glDropdown'
$.data this, 'glDropdown', new GitLabDropdown this, opts
return @.each ->
if (!$.data @, 'glDropdown')
$.data(@, 'glDropdown', new GitLabDropdown @, opts)
......@@ -315,11 +315,10 @@ class @SearchAutocomplete
disableAutocomplete: ->
# If not disabled already, disable
if not @searchInput.hasClass('disabled') && @dropdown.hasClass('open')
if not @searchInput.hasClass('disabled') and @dropdown.hasClass 'open'
@searchInput.addClass('disabled')
# Close dropdown and invoke its hidden() method
@dropdown.removeClass('open')
.trigger('hidden.bs.dropdown')
@dropdown.removeClass('open').trigger 'hidden.bs.dropdown'
@restoreMenu()
restoreMenu: ->
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment