浏览代码

use index in choice elements to fix #102

Falko Schindler 2 年之前
父节点
当前提交
8991ce158f
共有 3 个文件被更改,包括 24 次插入22 次删除
  1. 18 6
      nicegui/elements/choice_element.py
  2. 4 14
      nicegui/elements/select.py
  3. 2 2
      nicegui/elements/value_element.py

+ 18 - 6
nicegui/elements/choice_element.py

@@ -1,4 +1,4 @@
-from typing import Any, Callable, Dict, List, Optional, Union
+from typing import Any, Callable, Dict, List, Literal, Optional, Union
 
 import justpy as jp
 
@@ -8,10 +8,22 @@ from .value_element import ValueElement
 class ChoiceElement(ValueElement):
 
     def __init__(self, view: jp.HTMLBaseComponent, options: Union[List, Dict], *,
-                 value: Any, on_change: Optional[Callable] = None):
-        if isinstance(options, List):
-            view.options = [{'label': option, 'value': option} for option in options]
-        else:
-            view.options = [{'label': value, 'value': key} for key, value in options.items()]
+                 value: Any, on_change: Optional[Callable] = None) -> None:
+        self.values = options if isinstance(options, list) else list(options.keys())
+        self.labels = options if isinstance(options, list) else list(options.values())
+        view.options = [{'value': index, 'label': option} for index, option in enumerate(self.labels)]
 
         super().__init__(view, value=value, on_change=on_change)
+
+    def value_to_view(self, value: Any):
+        try:
+            return self.values.index(value)
+        except ValueError:
+            return value
+
+    def handle_change(self, msg: Dict) -> Literal[False]:
+        index = msg['value']['value'] if isinstance(msg['value'], dict) else msg['value']
+        msg['index'] = index
+        msg['label'] = self.labels[index]
+        msg['value'] = self.values[index]
+        return super().handle_change(msg)

+ 4 - 14
nicegui/elements/select.py

@@ -8,7 +8,7 @@ from .choice_element import ChoiceElement
 class Select(ChoiceElement):
 
     def __init__(self, options: Union[List, Dict], *,
-                 label: Optional[str] = None, value: Any = None, on_change: Optional[Callable] = None):
+                 label: Optional[str] = None, value: Any = None, on_change: Optional[Callable] = None) -> None:
         """Dropdown Selection
 
         :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options
@@ -20,17 +20,7 @@ class Select(ChoiceElement):
         super().__init__(view, options, value=value, on_change=on_change)
 
     def value_to_view(self, value: Any):
-        if isinstance(value, list):
-            value = tuple(value)
-        matches = [o for o in self.view.options if o['value'] == value]
-        if any(matches):
-            return matches[0]['label']
-        else:
+        try:
+            return self.labels[self.values.index(value)]
+        except ValueError:
             return value
-
-    def handle_change(self, msg: Dict):
-        msg['label'] = msg['value']['label']
-        msg['value'] = msg['value']['value']
-        if isinstance(self.view.options[0]['value'], tuple) and isinstance(msg['value'], list):
-            msg['value'] = tuple(msg['value'])
-        return super().handle_change(msg)

+ 2 - 2
nicegui/elements/value_element.py

@@ -1,4 +1,4 @@
-from typing import Any, Callable, Dict, Optional
+from typing import Any, Callable, Dict, Literal, Optional
 
 import justpy as jp
 
@@ -25,7 +25,7 @@ class ValueElement(Element):
     def set_value(self, value) -> None:
         self.value = value
 
-    def handle_change(self, msg: Dict):
+    def handle_change(self, msg: Dict) -> Literal[False]:
         self.value = msg['value']
         self.update()
         return False