Ver código fonte

preserve filtered options during multi-select (fixes #2015)

Falko Schindler 1 ano atrás
pai
commit
b9229b8869
2 arquivos alterados com 38 adições e 6 exclusões
  1. 13 6
      nicegui/elements/select.js
  2. 25 0
      tests/test_select.py

+ 13 - 6
nicegui/elements/select.js

@@ -20,13 +20,20 @@ export default {
   },
   methods: {
     filterFn(val, update, abort) {
-      update(() => {
-        const needle = val.toLocaleLowerCase();
-        this.filteredOptions = needle
-          ? this.initialOptions.filter((v) => String(v.label).toLocaleLowerCase().indexOf(needle) > -1)
-          : this.initialOptions;
-      });
+      update(() => (this.filteredOptions = this.findFilteredOptions()));
     },
+    findFilteredOptions() {
+      const needle = this.$el.querySelector("input[type=search]")?.value.toLocaleLowerCase();
+      return needle
+        ? this.initialOptions.filter((v) => String(v.label).toLocaleLowerCase().indexOf(needle) > -1)
+        : this.initialOptions;
+    },
+  },
+  updated() {
+    const newFilteredOptions = this.findFilteredOptions();
+    if (newFilteredOptions.length !== this.filteredOptions.length) {
+      this.filteredOptions = newFilteredOptions;
+    }
   },
   watch: {
     options: {

+ 25 - 0
tests/test_select.py

@@ -140,3 +140,28 @@ def test_add_new_values(screen:  Screen, option_dict: bool, multiple: bool, new_
             screen.should_contain("value = ['a']" if multiple else 'value = None')
             screen.should_contain("options = {'a': 'A', 'b': 'B', 'c': 'C'}" if option_dict else
                                   "options = ['a', 'b', 'c']")
+
+
+def test_keep_filtered_options(screen: Screen):
+    ui.select(options=['A1', 'A2', 'B1', 'B2'], with_input=True, multiple=True)
+
+    screen.open('/')
+    screen.find_by_tag('input').click()
+    screen.should_contain('A1')
+    screen.should_contain('A2')
+    screen.should_contain('B1')
+    screen.should_contain('B2')
+
+    screen.find_by_tag('input').send_keys('A')
+    screen.wait(0.5)
+    screen.should_contain('A1')
+    screen.should_contain('A2')
+    screen.should_not_contain('B1')
+    screen.should_not_contain('B2')
+
+    screen.click('A1')
+    screen.wait(0.5)
+    screen.should_contain('A1')
+    screen.should_contain('A2')
+    screen.should_not_contain('B1')
+    screen.should_not_contain('B2')