From 2a53d1f1d00378457d598441da986d1721599d2f Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Fri, 5 May 2017 15:05:41 +0200 Subject: [PATCH] Added 'unknown' attribute to searchable select input to allow values not available in the list. --- .../app/lib/app_post/searchable_select.coffee | 20 +++++- public/assets/tests/form_searchable_select.js | 70 ++++++++++++++++--- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/app/lib/app_post/searchable_select.coffee b/app/assets/javascripts/app/lib/app_post/searchable_select.coffee index 72240602b..a072a057f 100644 --- a/app/assets/javascripts/app/lib/app_post/searchable_select.coffee +++ b/app/assets/javascripts/app/lib/app_post/searchable_select.coffee @@ -32,6 +32,8 @@ class App.SearchableSelect extends Spine.Controller if firstSelected @options.attribute.valueName = firstSelected.name @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: @options.attribute.options @@ -142,9 +144,14 @@ class App.SearchableSelect extends Spine.Controller 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') - @shadowInput.val @option_items.filter('.is-active').attr('data-value') @shadowInput.trigger('change') @toggle() @@ -162,6 +169,9 @@ class App.SearchableSelect extends Spine.Controller @query = @input.val() @filterByQuery @query + if @options.attribute.unknown + @shadowInput.val @query + filterByQuery: (query) -> query = escapeRegExp(query) regex = new RegExp(query.split(' ').join('.*'), 'i') @@ -172,7 +182,11 @@ class App.SearchableSelect extends Spine.Controller @textContent.match(regex) .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) -> first = @option_items.removeClass('is-active').not('.is-hidden').first() diff --git a/public/assets/tests/form_searchable_select.js b/public/assets/tests/form_searchable_select.js index 4628bff54..61712d703 100644 --- a/public/assets/tests/form_searchable_select.js +++ b/public/assets/tests/form_searchable_select.js @@ -15,8 +15,31 @@ test( "searchable_select check", function() { el: el, model: { 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 @@ -26,36 +49,67 @@ test( "searchable_select check", function() { var test_params = { searchable_select1: '', searchable_select2: 'bbb', + searchable_select3: '', } deepEqual( params, test_params, 'form param check' ) // change selection $('[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') $('[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') - $('[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 ) test_params = { searchable_select1: 'ccc', searchable_select2: 'bbb', + searchable_select3: '', } deepEqual( params, test_params, 'form param check' ) $('[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') $('[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') - $('[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 ) test_params = { searchable_select1: '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' )