Added 'unknown' attribute to searchable select input to allow values not available in the list.

This commit is contained in:
Thorsten Eckel 2017-05-05 15:05:41 +02:00
parent 451f31f7cf
commit 2a53d1f1d0
2 changed files with 79 additions and 11 deletions

View file

@ -32,6 +32,8 @@ class App.SearchableSelect extends Spine.Controller
if firstSelected if firstSelected
@options.attribute.valueName = firstSelected.name @options.attribute.valueName = firstSelected.name
@options.attribute.value = firstSelected.value @options.attribute.value = firstSelected.value
else if @options.attribute.unknown && @options.attribute.value
@options.attribute.valueName = @options.attribute.value
@options.attribute.renderedOptions = App.view('generic/searchable_select_options') @options.attribute.renderedOptions = App.view('generic/searchable_select_options')
options: @options.attribute.options options: @options.attribute.options
@ -142,9 +144,14 @@ class App.SearchableSelect extends Spine.Controller
event.preventDefault() event.preventDefault()
@input.val @option_items.filter('.is-active').text().trim() selected = @option_items.filter('.is-active')
if selected.length || !@options.attribute.unknown
valueName = selected.text().trim()
value = selected.attr('data-value')
@input.val valueName
@shadowInput.val value
@input.trigger('change') @input.trigger('change')
@shadowInput.val @option_items.filter('.is-active').attr('data-value')
@shadowInput.trigger('change') @shadowInput.trigger('change')
@toggle() @toggle()
@ -162,6 +169,9 @@ class App.SearchableSelect extends Spine.Controller
@query = @input.val() @query = @input.val()
@filterByQuery @query @filterByQuery @query
if @options.attribute.unknown
@shadowInput.val @query
filterByQuery: (query) -> filterByQuery: (query) ->
query = escapeRegExp(query) query = escapeRegExp(query)
regex = new RegExp(query.split(' ').join('.*'), 'i') regex = new RegExp(query.split(' ').join('.*'), 'i')
@ -172,7 +182,11 @@ class App.SearchableSelect extends Spine.Controller
@textContent.match(regex) @textContent.match(regex)
.removeClass 'is-hidden' .removeClass 'is-hidden'
@highlightFirst(true) if @options.attribute.unknown && @option_items.length == @option_items.filter('.is-hidden').length
@option_items.removeClass 'is-hidden'
@option_items.removeClass 'is-active'
else
@highlightFirst(true)
highlightFirst: (autocomplete) -> highlightFirst: (autocomplete) ->
first = @option_items.removeClass('is-active').not('.is-hidden').first() first = @option_items.removeClass('is-active').not('.is-hidden').first()

View file

@ -15,8 +15,31 @@ test( "searchable_select check", function() {
el: el, el: el,
model: { model: {
configure_attributes: [ configure_attributes: [
{ name: 'searchable_select1', display: 'SearchableSelect1', tag: 'searchable_select', options: options, null: true, default: defaults['searchable_select1'] }, {
{ name: 'searchable_select2', display: 'SearchableSelect2', tag: 'searchable_select', options: options, null: false, default: defaults['searchable_select2'] }, name: 'searchable_select1',
display: 'SearchableSelect1',
tag: 'searchable_select',
options: options,
null: true,
default: defaults['searchable_select1']
},
{
name: 'searchable_select2',
display: 'SearchableSelect2',
tag: 'searchable_select',
options: options,
null: false,
default: defaults['searchable_select2']
},
{
name: 'searchable_select3',
display: 'SearchableSelect3',
tag: 'searchable_select',
options: options,
default: defaults['searchable_select3'],
null: true,
unknown: true
},
] ]
}, },
autofocus: true autofocus: true
@ -26,36 +49,67 @@ test( "searchable_select check", function() {
var test_params = { var test_params = {
searchable_select1: '', searchable_select1: '',
searchable_select2: 'bbb', searchable_select2: 'bbb',
searchable_select3: '',
} }
deepEqual( params, test_params, 'form param check' ) deepEqual( params, test_params, 'form param check' )
// change selection // change selection
$('[name="searchable_select1"].js-shadow + .js-input').focus().val('').trigger('input') $('[name="searchable_select1"].js-shadow + .js-input').focus().val('').trigger('input')
var entries = $('[name="searchable_select1"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').length var $element = $('[name="searchable_select1"]').closest('.searchableSelect').find('.js-optionsList')
var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 3, 'dropdown count') equal(entries, 3, 'dropdown count')
$('[name="searchable_select1"].js-shadow + .js-input').focus().val('ccc display').trigger('input') $('[name="searchable_select1"].js-shadow + .js-input').focus().val('ccc display').trigger('input')
var entries = $('[name="searchable_select1"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').length var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 1, 'dropdown count') equal(entries, 1, 'dropdown count')
$('[name="searchable_select1"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').first().click() $element.find('li:not(.is-hidden)').first().click()
params = App.ControllerForm.params( el ) params = App.ControllerForm.params( el )
test_params = { test_params = {
searchable_select1: 'ccc', searchable_select1: 'ccc',
searchable_select2: 'bbb', searchable_select2: 'bbb',
searchable_select3: '',
} }
deepEqual( params, test_params, 'form param check' ) deepEqual( params, test_params, 'form param check' )
$('[name="searchable_select2"].js-shadow + .js-input').focus().val('').trigger('input') $('[name="searchable_select2"].js-shadow + .js-input').focus().val('').trigger('input')
var entries = $('[name="searchable_select2"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').length var $element = $('[name="searchable_select2"]').closest('.searchableSelect').find('.js-optionsList')
var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 3, 'dropdown count') equal(entries, 3, 'dropdown count')
$('[name="searchable_select2"].js-shadow + .js-input').focus().val('ccc display').trigger('input') $('[name="searchable_select2"].js-shadow + .js-input').focus().val('ccc display').trigger('input')
var entries = $('[name="searchable_select2"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').length var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 1, 'dropdown count') equal(entries, 1, 'dropdown count')
$('[name="searchable_select2"]').closest('.searchableSelect').find('.js-optionsList li:not(.is-hidden)').first().click() $element.find('li:not(.is-hidden)').first().click()
params = App.ControllerForm.params( el ) params = App.ControllerForm.params( el )
test_params = { test_params = {
searchable_select1: 'ccc', searchable_select1: 'ccc',
searchable_select2: 'ccc', searchable_select2: 'ccc',
searchable_select3: '',
}
deepEqual( params, test_params, 'form param check' )
$('[name="searchable_select3"].js-shadow + .js-input').focus().val('').trigger('input')
var $element = $('[name="searchable_select3"]').closest('.searchableSelect').find('.js-optionsList')
var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 3, 'dropdown count')
$('[name="searchable_select3"].js-shadow + .js-input').focus().val('ccc display').trigger('input')
var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 1, 'dropdown count')
$('[name="searchable_select3"].js-shadow + .js-input').focus().val('unknown value').trigger('input')
var entries = $element.find('li:not(.is-hidden)').length
equal(entries, 3, 'dropdown count')
var entries = $element.find('li.is-active').length
equal(entries, 0, 'active count')
var e = $.Event('keydown')
e.which = 13 //enter
e.keyCode = 13
$('[name="searchable_select3"].js-shadow + .js-input').trigger(e)
params = App.ControllerForm.params( el )
test_params = {
searchable_select1: 'ccc',
searchable_select2: 'ccc',
searchable_select3: 'unknown value',
} }
deepEqual( params, test_params, 'form param check' ) deepEqual( params, test_params, 'form param check' )