From 4c860150744459f64e70d842f112d75e0bf1973f Mon Sep 17 00:00:00 2001 From: Bola Ahmed Buari Date: Wed, 24 Feb 2021 14:04:38 +0000 Subject: [PATCH] Fixes #3162 - Backslash "\" causes tree select to disappear during selection. --- .../app/lib/app_post/searchable_select.coffee | 10 ++- .../generic/searchable_select_submenu.jst.eco | 6 +- public/assets/tests/form_searchable_select.js | 54 ++++++++++++ public/assets/tests/form_tree_select.js | 83 +++++++++++++++++++ 4 files changed, 147 insertions(+), 6 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 f42052db6..3a2e28acb 100644 --- a/app/assets/javascripts/app/lib/app_post/searchable_select.coffee +++ b/app/assets/javascripts/app/lib/app_post/searchable_select.coffee @@ -159,7 +159,9 @@ class App.SearchableSelect extends Spine.Controller @currentMenu.find('.js-option, .js-enter, .js-back') getOptionIndex: (menu, value) -> - menu.find('.js-option, .js-enter').filter("[data-value=\"#{value}\"]").index() + menu.find('.js-option, .js-enter') + .filter((i, el) -> $(el).attr('data-value') is value) + .index() nudge: (event, direction) -> return @toggle() if not @isOpen @@ -249,7 +251,7 @@ class App.SearchableSelect extends Spine.Controller return if @animating if dir > 0 target = @currentItem.attr('data-value') - target_menu = @optionsSubmenu.filter("[data-parent-value=\"#{target}\"]") + target_menu = @optionsSubmenu.filter((i, el) -> $(el).attr('data-parent-value') is target) else target_menu = @findMenuContainingValue(@currentMenu.attr('data-parent-value')) @@ -309,9 +311,11 @@ class App.SearchableSelect extends Spine.Controller return @optionsList else path.pop() - return @optionsSubmenu.filter("[data-parent-value=\"#{path.join('::')}\"]") + target = path.join('::') + return @optionsSubmenu.filter((i, el) -> $(el).attr('data-parent-value') is target) getIndex: (menu) -> + return 0 if !menu parentValue = menu.attr('data-parent-value') return 0 if !parentValue return parentValue.split('::').length diff --git a/app/assets/javascripts/app/views/generic/searchable_select_submenu.jst.eco b/app/assets/javascripts/app/views/generic/searchable_select_submenu.jst.eco index 204f2f639..e0cb323ee 100644 --- a/app/assets/javascripts/app/views/generic/searchable_select_submenu.jst.eco +++ b/app/assets/javascripts/app/views/generic/searchable_select_submenu.jst.eco @@ -1,11 +1,11 @@ - diff --git a/public/assets/tests/form_searchable_select.js b/public/assets/tests/form_searchable_select.js index 81037e757..826928503 100644 --- a/public/assets/tests/form_searchable_select.js +++ b/public/assets/tests/form_searchable_select.js @@ -183,5 +183,59 @@ test( "searchable_select check", function() { 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') +}); + +asyncTest("searchable_select submenu and option list check", function() { + expect(3); + + $('#forms').append('

searchable_select check for special charaters values

') + var el = $('#form3') + var defaults = { + searchable_select1: 'aaa', + } + var options = [ + { value: 'aaa', name: 'aaa display' }, + { value: 'bbb', name: 'bbb display' }, + { value: 'c\\cc', name: 'ccc display', children: [ + { value: 'c\\cc::aaa', name: 'aaa display L2' }, + { value: 'c\\cc::bbb', name: 'bbb display L2' }, + { value: 'c\\cc::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, + }, + ] + }, + }) + + el.find("[name=\"searchable_select1\"].js-shadow + .js-input").click() + el.find(".searchableSelect .js-optionsList [data-value=\"c\\\\cc\"]").mouseenter().click() + el.find(".searchableSelect .js-optionsSubmenu [data-value=\"c\\\\cc::bbb\"]").mouseenter().click() + el.find("[name=\"searchable_select1\"].js-shadow + .js-input").click() + + var params = App.ControllerForm.params(el) + var test_params = { + searchable_select1: 'c\\cc::bbb' + } + + var optionsSubmenu = el.find(".searchableSelect .js-optionsSubmenu") + var optionsList = el.find(".searchableSelect .js-optionsList") + + setTimeout( () => { + deepEqual(params, test_params, 'form param check') + equal(optionsSubmenu.is('[hidden]'), false, 'options submenu menu not hidden') + equal(optionsList.is('[hidden]'), true, 'options list is hidden') + start(); + }, 300) }); diff --git a/public/assets/tests/form_tree_select.js b/public/assets/tests/form_tree_select.js index 570541d76..a19f2de47 100644 --- a/public/assets/tests/form_tree_select.js +++ b/public/assets/tests/form_tree_select.js @@ -268,3 +268,86 @@ test("form elements check", function() { deepEqual(params, test_params, 'form param check') }); + +asyncTest("searchable_select submenu and option list check", function() { + expect(3); + + + $('#forms').append('

form elements check

') + var el = $('#form5') + new App.ControllerForm({ + el: el, + model: { + "configure_attributes": [ + { + "name": "tree_select", + "display": "tree_select", + "tag": "tree_select", + "null": true, + "translate": true, + "value": "bb", + "options": [ + { + "value": "a\\a", + "name": "a\\a", + "children": [ + { + "value": "a\\a::aaa", + "name": "aaa", + }, + { + "value": "a\\a::aab", + "name": "aab", + }, + { + "value": "a\\a::aac", + "name": "aac", + }, + ] + }, + { + "value": "bb", + "name": "bb", + "children": [ + { + "value": "bb::bba", + "name": "bba", + }, + { + "value": "bb::bbb", + "name": "bbb", + }, + { + "value": "bb::bbc", + "name": "bbc", + }, + ] + }, + ], + } + ] + }, + autofocus: true + }); + + el.find("[name=\"tree_select\"].js-shadow + .js-input").click() + el.find(".searchableSelect .js-optionsList [data-value=\"a\\\\a\"]").mouseenter().click() + el.find(".searchableSelect .js-optionsSubmenu [data-value=\"a\\\\a::aab\"]").mouseenter().click() + el.find("[name=\"tree_select\"].js-shadow + .js-input").click() + + var params = App.ControllerForm.params(el) + var test_params = { + tree_select: 'a\\a::aab' + } + + var optionsSubmenu = el.find(".searchableSelect [data-parent-value=\"a\\\\a\"].js-optionsSubmenu") + var optionsList = el.find(".searchableSelect .js-optionsList") + + setTimeout( () => { + deepEqual(params, test_params, 'form param check') + equal(optionsSubmenu.is('[hidden]'), false, 'options submenu menu not hidden') + equal(optionsList.is('[hidden]'), true, 'options list is hidden') + start(); + }, 300) + +});