Browse Source

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

Thorsten Eckel 7 years ago
parent
commit
2a53d1f1d0

+ 17 - 3
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()

+ 62 - 8
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' )