فهرست منبع

Adjusting validation element for better err_msg

This patch adjust validation element to allow user to
specify validation function that dynamically returns
error message
Stefan Gula 1 سال پیش
والد
کامیت
c787adc494
1فایلهای تغییر یافته به همراه59 افزوده شده و 10 حذف شده
  1. 59 10
      nicegui/elements/mixins/validation_element.py

+ 59 - 10
nicegui/elements/mixins/validation_element.py

@@ -1,30 +1,79 @@
-from typing import Any, Callable, Dict, Optional
+from typing import Any, Callable, Dict, Optional, Union, Tuple, List
 
 from .value_element import ValueElement
 
 
 class ValidationElement(ValueElement):
 
-    def __init__(self, validation: Dict[str, Callable[..., bool]], **kwargs: Any) -> None:
+    def __init__(self, validation: Union[List[Callable[..., Tuple[bool, str]]], Dict[str, Callable[..., bool]]], **kwargs: Any) -> None:
         super().__init__(**kwargs)
         self.validation = validation
         self._error: Optional[str] = None
+        self._validate_individually = False
 
     @property
     def error(self) -> Optional[str]:
         """The latest error message from the validation functions."""
         return self._error
 
+    @error.setter
+    def error(self, error: Optional[str]) -> None:
+        """The setter for an error.
+
+        :param error: Optional error message
+        """
+        self._error = error
+
+    def set_validate_individually(self, value: bool) -> None:
+        """Sets whether or not the validate value elements individually.
+
+        :param value: Whether or not to evaluate value elements individually
+        """
+        self._validate_individually = value
+
+    def _set_error_message(self, message: str) -> None:
+        """Sets the error message.
+
+        :param message: The error message
+        """
+        message = message.replace('"', '\\"')
+        self._error = message
+        self.props(f'error error-message="{message}"')
+
+    def _clear_error_message(self) -> None:
+        """Clears the error message."""
+        self._error = None
+        self.props(remove='error')
+
+    def _validate_single_value(self, value: Any) -> bool:
+        """Validates single value element and sets the error message if necessary.
+
+        :param value: The single value element
+        :return: True if given single value element is valid, otherwise false
+        :rtype: bool
+        """
+        if isinstance(self.validation, dict):
+            for message, check in self.validation.items():
+                if not check(self.value):
+                    self._set_error_message(message)
+                    return False
+        else:
+            for check in self.validation:
+                ret, message = check(value)
+                if not ret:
+                    self._set_error_message(message)
+                    return False
+        return True
+
     def validate(self) -> None:
         """Validate the current value and set the error message if necessary."""
-        for message, check in self.validation.items():
-            if not check(self.value):
-                self._error = message
-                self.props(f'error error-message="{message}"')
-                break
-        else:
-            self._error = None
-            self.props(remove='error')
+        if self._validate_individually and isinstance(self.value, list):
+            for value in self.value:
+                if not self._validate_single_value(value):
+                    return
+        elif not self._validate_single_value(self.value):
+            return
+        self._clear_error_message()
 
     def _handle_value_change(self, value: Any) -> None:
         super()._handle_value_change(value)