Bläddra i källkod

fix choice elements

Falko Schindler 2 år sedan
förälder
incheckning
212724f5e7

+ 2 - 2
api_docs_and_examples.py

@@ -155,7 +155,7 @@ def create_full() -> None:
         radio1 = ui.radio([1, 2, 3], value=1).props('inline')
         radio2 = ui.radio({1: 'A', 2: 'B', 3: 'C'}).props('inline').bind_value(radio1, 'value')
 
-    @example(ui.select)
+    @example(ui.select, skip=False)
     def select_example():
         select1 = ui.select([1, 2, 3], value=1)
         select2 = ui.select({1: 'One', 2: 'Two', 3: 'Three'}).bind_value(select1, 'value')
@@ -602,7 +602,7 @@ Just pass a property of the model as parameter to these methods to create the bi
         v = ui.checkbox('visible', value=True)
         with ui.column().bind_visibility_from(v, 'value'):
             ui.slider(min=1, max=3).bind_value(demo, 'number')
-            ui.toggle({1: 'a', 2: 'b', 3: 'c'}).bind_value(demo, 'number')
+            ui.toggle({1: 'A', 2: 'B', 3: 'C'}).bind_value(demo, 'number')
             ui.number().bind_value(demo, 'number')
 
     @example('''#### UI Updates

+ 1 - 1
nicegui/elements/choice_element.py

@@ -19,9 +19,9 @@ class ChoiceElement(ValueElement):
         self._labels = self.options if isinstance(self.options, list) else list(self.options.values())
 
     def _update_options(self) -> None:
-        self._update_values_and_labels()
         self._props['options'] = [{'value': index, 'label': option} for index, option in enumerate(self._labels)]
 
     def update(self) -> None:
+        self._update_values_and_labels()
         self._update_options()
         super().update()

+ 8 - 8
nicegui/elements/mixins/value_element.py

@@ -10,13 +10,13 @@ class ValueElement(Element):
 
     def __init__(self, *, value: Any, on_value_change: Callable, **kwargs) -> None:
         super().__init__(**kwargs)
-        self.value = value
-        self._props['model-value'] = self._value_to_model(value)
+        self.set_value(value)
+        self._props['model-value'] = self._value_to_model_value(value)
         self.change_handler = on_value_change
 
         def handle_change(msg: Dict) -> None:
-            self.value = self._msg_to_value(msg)
-        self.on('update:model-value', handle_change, ['value', 'label'])
+            self.set_value(self._msg_to_value(msg))
+        self.on('update:model-value', handle_change, ['value'])
 
     def bind_value_to(self, target_object: Any, target_name: str = 'value', forward: Callable = lambda x: x):
         bind_to(self, 'value', target_object, target_name, forward)
@@ -31,11 +31,11 @@ class ValueElement(Element):
         bind(self, 'value', target_object, target_name, forward=forward, backward=backward)
         return self
 
-    def set_value(self, value: str) -> None:
+    def set_value(self, value: Any) -> None:
         self.value = value
 
-    def on_value_change(self, value: str) -> None:
-        self._props['model-value'] = self._value_to_model(value)
+    def on_value_change(self, value: Any) -> None:
+        self._props['model-value'] = self._value_to_model_value(value)
         self.update()
         args = ValueChangeEventArguments(sender=self, client=self.client, value=self._value_to_event_value(value))
         handle_event(self.change_handler, args)
@@ -43,7 +43,7 @@ class ValueElement(Element):
     def _msg_to_value(self, msg: Dict) -> Any:
         return msg['args']
 
-    def _value_to_model(self, value: Any) -> Any:
+    def _value_to_model_value(self, value: Any) -> Any:
         return value
 
     def _value_to_event_value(self, value: Any) -> Any:

+ 5 - 2
nicegui/elements/number.py

@@ -1,4 +1,4 @@
-from typing import Any, Callable, Optional
+from typing import Any, Callable, Dict, Optional
 
 from .mixins.value_element import ValueElement
 
@@ -25,7 +25,10 @@ class Number(ValueElement):
         self._props['label'] = label
         self._props['placeholder'] = placeholder
 
-    def _value_to_model(self, value: Any) -> Any:
+    def _msg_to_value(self, msg: Dict) -> Any:
+        return float(msg['args'])
+
+    def _value_to_model_value(self, value: Any) -> Any:
         if value is None:
             return None
         elif self.format is None:

+ 2 - 2
nicegui/elements/radio.py

@@ -17,5 +17,5 @@ class Radio(ChoiceElement):
     def _msg_to_value(self, msg: Dict) -> Any:
         return self._values[msg['args']]
 
-    def _value_to_model(self, value: Any) -> Any:
-        return self._values.index(value) if value in self._values else value
+    def _value_to_model_value(self, value: Any) -> Any:
+        return self._values.index(value) if value in self._values else None

+ 8 - 8
nicegui/elements/select.py

@@ -1,6 +1,5 @@
 from typing import Any, Callable, Dict, List, Optional, Union
 
-from ..events import ValueChangeEventArguments, handle_event
 from .choice_element import ChoiceElement
 
 
@@ -18,10 +17,11 @@ class Select(ChoiceElement):
         self._props['label'] = label
 
     def _msg_to_value(self, msg: Dict) -> Any:
-        return msg['args']['value']
-
-    def _value_to_model(self, value: Any) -> Any:
-        return self._labels[self._values.index(value)] if isinstance(value, str) else self._labels[value]
-
-    def _value_to_event_value(self, value: Any) -> Any:
-        return self._values[value]
+        return self._values[msg['args']['value']]
+
+    def _value_to_model_value(self, value: Any) -> Any:
+        try:
+            index = self._values.index(value)
+            return {'value': index, 'label': self._labels[index]}
+        except ValueError:
+            return None

+ 3 - 6
nicegui/elements/toggle.py

@@ -15,10 +15,7 @@ class Toggle(ChoiceElement):
         super().__init__(tag='q-btn-toggle', options=options, value=value, on_change=on_change)
 
     def _msg_to_value(self, msg: Dict) -> Any:
-        return msg['args']
+        return self._values[msg['args']]
 
-    def _value_to_model(self, value: Any) -> Any:
-        return self._values.index(value) if value in self._values else value
-
-    def _value_to_event_value(self, value: Any) -> Any:
-        return self._values[value]
+    def _value_to_model_value(self, value: Any) -> Any:
+        return self._values.index(value) if value in self._values else None