浏览代码

allow changing the options of choice elements

Falko Schindler 2 年之前
父节点
当前提交
e5431c8def
共有 3 个文件被更改,包括 38 次插入8 次删除
  1. 16 7
      nicegui/elements/choice_element.py
  2. 1 1
      nicegui/elements/select.py
  3. 21 0
      tests/test_element.py

+ 16 - 7
nicegui/elements/choice_element.py

@@ -9,21 +9,30 @@ class ChoiceElement(ValueElement):
 
 
     def __init__(self, view: jp.HTMLBaseComponent, options: Union[List, Dict], *,
     def __init__(self, view: jp.HTMLBaseComponent, options: Union[List, Dict], *,
                  value: Any, on_change: Optional[Callable] = None) -> None:
                  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)]
-
+        self.options = options
+        self._values: List[str] = []
+        self._labels: List[str] = []
+        self._update_options(view)
         super().__init__(view, value=value, on_change=on_change)
         super().__init__(view, value=value, on_change=on_change)
 
 
     def value_to_view(self, value: Any):
     def value_to_view(self, value: Any):
         try:
         try:
-            return self.values.index(value)
+            return self._values.index(value)
         except ValueError:
         except ValueError:
             return value
             return value
 
 
     def handle_change(self, msg: Dict):
     def handle_change(self, msg: Dict):
         index = msg['value']['value'] if isinstance(msg['value'], dict) else msg['value']
         index = msg['value']['value'] if isinstance(msg['value'], dict) else msg['value']
         msg['index'] = index
         msg['index'] = index
-        msg['label'] = self.labels[index]
-        msg['value'] = self.values[index]
+        msg['label'] = self._labels[index]
+        msg['value'] = self._values[index]
         return super().handle_change(msg)
         return super().handle_change(msg)
+
+    def _update_options(self, view: jp.HTMLBaseComponent) -> None:
+        self._values = self.options if isinstance(self.options, list) else list(self.options.keys())
+        self._labels = self.options if isinstance(self.options, list) else list(self.options.values())
+        view.options = [{'value': index, 'label': option} for index, option in enumerate(self._labels)]
+
+    def update(self) -> None:
+        self._update_options(self.view)
+        super().update()

+ 1 - 1
nicegui/elements/select.py

@@ -21,6 +21,6 @@ class Select(ChoiceElement):
 
 
     def value_to_view(self, value: Any):
     def value_to_view(self, value: Any):
         try:
         try:
-            return self.labels[self.values.index(value)]
+            return self._labels[self._values.index(value)]
         except ValueError:
         except ValueError:
             return value
             return value

+ 21 - 0
tests/test_element.py

@@ -144,3 +144,24 @@ def test_props(screen: Screen):
 
 
     input.props(remove='dark')
     input.props(remove='dark')
     assert_props('standard', 'labeled')
     assert_props('standard', 'labeled')
+
+
+def test_adding_toggle_options(screen: Screen):
+    label = ui.label()
+    toggle = ui.toggle(['A', 'B', 'C'], on_change=lambda e: label.set_text(f'Choice: {e.value}'))
+
+    def add_option():
+        toggle.options.append('D')
+        toggle.update()
+
+    ui.button('Add option', on_click=add_option)
+
+    screen.open('/')
+    screen.click('A')
+    screen.should_contain('Choice: A')
+
+    screen.should_not_contain('D')
+    screen.click('Add option')
+    screen.should_contain('D')
+    screen.click('D')
+    screen.should_contain('Choice: D')