Fixes #2614 - Tree Select shows empty value in ticket zoom after submit when value contains trailing spaces.

This commit is contained in:
Martin Edenhofer 2019-06-24 01:15:27 +02:00
parent af9fcf4565
commit bd5170b731
3 changed files with 98 additions and 26 deletions

View file

@ -7,7 +7,7 @@ treeParams = (e, params) ->
$(e.target).closest('.modal').find('.js-treeTable .js-key').each( -> $(e.target).closest('.modal').find('.js-treeTable .js-key').each( ->
$element = $(@) $element = $(@)
level = parseInt($element.attr('level')) level = parseInt($element.attr('level'))
name = $element.val() name = $element.val().trim()
item = item =
name: name name: name

View file

@ -40,29 +40,29 @@ class App.SearchableSelect extends Spine.Controller
@html App.view('generic/searchable_select') @html App.view('generic/searchable_select')
attribute: @attribute attribute: @attribute
options: @renderAllOptions '', @attribute.options, 0 options: @renderAllOptions('', @attribute.options, 0)
submenus: @renderSubmenus @attribute.options submenus: @renderSubmenus(@attribute.options)
# initial data # initial data
@currentMenu = @findMenuContainingValue @attribute.value @currentMenu = @findMenuContainingValue(@attribute.value)
@level = @getIndex @currentMenu @level = @getIndex(@currentMenu)
renderSubmenus: (options) -> renderSubmenus: (options) ->
html = '' html = ''
if options if options
for option in options for option in options
if option.children if option.children
html += App.view('generic/searchable_select_submenu') html += App.view('generic/searchable_select_submenu')(
options: @renderOptions(option.children) options: @renderOptions(option.children)
parentValue: option.value parentValue: option.value
title: option.name title: option.name
)
if @hasSubmenu(option.children) if @hasSubmenu(option.children)
html += @renderSubmenus option.children html += @renderSubmenus(option.children)
html html
updateAttributeValueName: -> updateAttributeValueName: ->
firstSelected = _.find @attribute.options, (option) -> option.selected firstSelected = _.find(@attribute.options, (option) -> option.selected)
if firstSelected if firstSelected
@attribute.valueName = firstSelected.name @attribute.valueName = firstSelected.name
@ -70,7 +70,7 @@ class App.SearchableSelect extends Spine.Controller
else if @attribute.unknown && @attribute.value else if @attribute.unknown && @attribute.value
@attribute.valueName = @attribute.value @attribute.valueName = @attribute.value
else if @hasSubmenu @attribute.options else if @hasSubmenu @attribute.options
@attribute.valueName = @getName @attribute.value, @attribute.options @attribute.valueName = @getName(@attribute.value, @attribute.options)
hasSubmenu: (options) -> hasSubmenu: (options) ->
return false if !options return false if !options
@ -83,7 +83,7 @@ class App.SearchableSelect extends Spine.Controller
if option.value is value if option.value is value
return option.name return option.name
if option.children if option.children
name = @getName value, option.children name = @getName(value, option.children)
return name if name isnt undefined return name if name isnt undefined
undefined undefined
@ -103,30 +103,31 @@ class App.SearchableSelect extends Spine.Controller
if level && level > 0 if level && level > 0
className += ' is-hidden is-child' className += ' is-hidden is-child'
html += App.view('generic/searchable_select_option') html += App.view('generic/searchable_select_option')(
option: option option: option
class: className class: className
detail: parentName detail: parentName
)
if option.children if option.children
html += @renderAllOptions "#{parentName}#{option.name}", option.children, level+1 html += @renderAllOptions("#{parentName}#{option.name}", option.children, level+1)
html html
onDropdownShown: => onDropdownShown: =>
@input.on 'click', @stopPropagation @input.on('click', @stopPropagation)
@highlightFirst() @highlightFirst()
if @level > 0 if @level > 0
@showSubmenu(@currentMenu) @showSubmenu(@currentMenu)
@isOpen = true @isOpen = true
onDropdownHidden: => onDropdownHidden: =>
@input.off 'click', @stopPropagation @input.off('click', @stopPropagation)
@unhighlightCurrentItem() @unhighlightCurrentItem()
@isOpen = false @isOpen = false
if !@input.val() if !@input.val()
@updateAttributeValueName() @updateAttributeValueName()
@input.val @attribute.valueName @input.val(@attribute.valueName)
onKeyUp: => onKeyUp: =>
return if @input.val().trim() isnt '' return if @input.val().trim() isnt ''
@ -141,13 +142,13 @@ class App.SearchableSelect extends Spine.Controller
navigate: (event) => navigate: (event) =>
switch event.keyCode switch event.keyCode
when 40 then @nudge event, 1 # down when 40 then @nudge(event, 1) # down
when 38 then @nudge event, -1 # up when 38 then @nudge(event, -1) # up
when 39 then @autocompleteOrNavigateIn event # right when 39 then @autocompleteOrNavigateIn(event) # right
when 37 then @autocompleteOrNavigateOut event # left when 37 then @autocompleteOrNavigateOut(event) # left
when 13 then @onEnter event when 13 then @onEnter(event)
when 27 then @onEscape event when 27 then @onEscape(event)
when 9 then @onTab event when 9 then @onTab(event)
onEscape: -> onEscape: ->
if @isOpen if @isOpen
@ -204,8 +205,8 @@ class App.SearchableSelect extends Spine.Controller
# current position # current position
caretPosition = @invisiblePart.text().length + 1 caretPosition = @invisiblePart.text().length + 1
@input.val @suggestion @input.val(@suggestion)
@shadowInput.val @suggestionValue @shadowInput.val(@suggestionValue)
@clearAutocomplete() @clearAutocomplete()
@toggle() @toggle()
@ -250,7 +251,7 @@ class App.SearchableSelect extends Spine.Controller
target = @currentItem.attr('data-value') target = @currentItem.attr('data-value')
target_menu = @optionsSubmenu.filter("[data-parent-value=\"#{target}\"]") target_menu = @optionsSubmenu.filter("[data-parent-value=\"#{target}\"]")
else else
target_menu = @findMenuContainingValue @currentMenu.attr('data-parent-value') target_menu = @findMenuContainingValue(@currentMenu.attr('data-parent-value'))
@animateToSubmenu(target_menu, dir) @animateToSubmenu(target_menu, dir)

View file

@ -5,12 +5,21 @@ test( "searchable_select check", function() {
var el = $('#form1') var el = $('#form1')
var defaults = { var defaults = {
searchable_select2: 'bbb', searchable_select2: 'bbb',
searchable_select4: 'ccc',
} }
var options = { var options = {
'aaa': 'aaa display', 'aaa': 'aaa display',
'bbb': 'bbb display', 'bbb': 'bbb display',
'ccc': 'ccc display', 'ccc': 'ccc display',
} }
var options_4_tree = [
{ value: 'aaa', name: 'aaa display' },
{ value: 'bbb', name: 'bbb display' },
{ value: 'ccc', name: 'ccc display', children: [
{ value: 'ccc::aaa', name: 'aaa display' },
{ value: 'ccc::bbb', name: 'bbb display' },
] },
]
new App.ControllerForm({ new App.ControllerForm({
el: el, el: el,
model: { model: {
@ -40,6 +49,15 @@ test( "searchable_select check", function() {
null: true, null: true,
unknown: true unknown: true
}, },
{
name: 'searchable_select4',
display: 'SearchableSelect4',
tag: 'searchable_select',
options: options_4_tree,
default: defaults['searchable_select4'],
null: true,
unknown: true
},
] ]
}, },
autofocus: true autofocus: true
@ -50,6 +68,7 @@ test( "searchable_select check", function() {
searchable_select1: '', searchable_select1: '',
searchable_select2: 'bbb', searchable_select2: 'bbb',
searchable_select3: '', searchable_select3: '',
searchable_select4: 'ccc',
} }
deepEqual(params, test_params, 'form param check') deepEqual(params, test_params, 'form param check')
@ -67,6 +86,7 @@ test( "searchable_select check", function() {
searchable_select1: 'ccc', searchable_select1: 'ccc',
searchable_select2: 'bbb', searchable_select2: 'bbb',
searchable_select3: '', searchable_select3: '',
searchable_select4: 'ccc',
} }
deepEqual(params, test_params, 'form param check') deepEqual(params, test_params, 'form param check')
@ -84,6 +104,7 @@ test( "searchable_select check", function() {
searchable_select1: 'ccc', searchable_select1: 'ccc',
searchable_select2: 'ccc', searchable_select2: 'ccc',
searchable_select3: '', searchable_select3: '',
searchable_select4: 'ccc',
} }
deepEqual(params, test_params, 'form param check') deepEqual(params, test_params, 'form param check')
@ -110,7 +131,57 @@ test( "searchable_select check", function() {
searchable_select1: 'ccc', searchable_select1: 'ccc',
searchable_select2: 'ccc', searchable_select2: 'ccc',
searchable_select3: 'unknown value', searchable_select3: 'unknown value',
searchable_select4: 'ccc',
} }
deepEqual(params, test_params, 'form param check') deepEqual(params, test_params, 'form param check')
$('#forms').append('<hr><h1>searchable_select check for .js-input field values</h1><form id="form2"></form>')
var el = $('#form2')
var defaults = {
searchable_select1: 'ccc::aaa',
searchable_select2: 'ccc::ccc',
}
var options = [
{ value: 'aaa', name: 'aaa display' },
{ value: 'bbb', name: 'bbb display' },
{ value: 'ccc', name: 'ccc display', children: [
{ value: 'ccc::aaa', name: 'aaa display L2' },
{ value: 'ccc::bbb', name: 'bbb display L2' },
{ value: 'ccc::ccc', name: 'ccc display L2' },
] },
]
new App.ControllerForm({
el: el,
model: {
configure_attributes: [
{
name: 'searchable_select1',
display: 'SearchableSelect1',
tag: 'searchable_select',
options: options,
default: defaults['searchable_select1'],
null: true,
},
{
name: 'searchable_select2',
display: 'SearchableSelect2',
tag: 'searchable_select',
options: options,
default: defaults['searchable_select2'],
null: true,
},
]
},
})
var params = App.ControllerForm.params(el)
var test_params = {
searchable_select1: 'ccc::aaa',
searchable_select2: 'ccc::ccc',
}
deepEqual(params, test_params, 'form param check')
equal(el.find('[name="searchable_select1"].js-shadow + .js-input').val(), 'aaa display L2', 'verify shown input')
equal(el.find('[name="searchable_select2"].js-shadow + .js-input').val(), 'ccc display L2', 'verify shown input')
}); });