Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide bottom space for error message when validation is None #3660

Merged
merged 1 commit into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nicegui/elements/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self,
:param password_toggle_button: whether to show a button to toggle the password visibility (default: False)
:param on_change: callback to execute when the value changes
:param autocomplete: optional list of strings for autocompletion
:param validation: dictionary of validation rules or a callable that returns an optional error message
:param validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)
"""
super().__init__(value=value, on_value_change=on_change, validation=validation)
if label is not None:
Expand Down
36 changes: 26 additions & 10 deletions nicegui/elements/mixins/validation_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,25 @@
class ValidationElement(ValueElement):

def __init__(self, validation: Optional[Union[Callable[..., Optional[str]], Dict[str, Callable[..., bool]]]], **kwargs: Any) -> None:
self.validation = validation if validation is not None else {}
self._validation = validation
self._auto_validation = True
self._error: Optional[str] = None
super().__init__(**kwargs)
self._props['error'] = False # NOTE: reserve bottom space for error message
self._props['error'] = None if validation is None else False # NOTE: reserve bottom space for error message

@property
def validation(self) -> Optional[Union[Callable[..., Optional[str]], Dict[str, Callable[..., bool]]]]:
"""The validation function or dictionary of validation functions."""
return self._validation

@validation.setter
def validation(self, validation: Optional[Union[Callable[..., Optional[str]], Dict[str, Callable[..., bool]]]]) -> None:
"""Sets the validation function or dictionary of validation functions.

:param validation: validation function or dictionary of validation functions (``None`` to disable validation)
"""
self._validation = validation
self.validate()

@property
def error(self) -> Optional[str]:
Expand All @@ -25,10 +39,11 @@ def error(self, error: Optional[str]) -> None:

:param error: The optional error message
"""
if self._error == error:
new_error_prop = None if self.validation is None else (error is not None)
if self._error == error and self._props['error'] == new_error_prop:
return
self._error = error
self._props['error'] = error is not None
self._props['error'] = new_error_prop
self._props['error-message'] = error
self.update()

Expand All @@ -37,14 +52,15 @@ def validate(self) -> bool:

:return: True if the value is valid, False otherwise
"""
if callable(self.validation):
self.error = self.validation(self.value)
if callable(self._validation):
self.error = self._validation(self.value)
return self.error is None

for message, check in self.validation.items():
if not check(self.value):
self.error = message
return False
if isinstance(self._validation, dict):
for message, check in self._validation.items():
if not check(self.value):
self.error = message
return False

self.error = None
return True
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self,
:param suffix: a suffix to append to the displayed value
:param format: a string like "%.2f" to format the displayed value
:param on_change: callback to execute when the value changes
:param validation: dictionary of validation rules or a callable that returns an optional error message
:param validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)
"""
self.format = format
super().__init__(tag='q-input', value=value, on_value_change=on_change, validation=validation)
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __init__(self,
:param new_value_mode: handle new values from user input (default: None, i.e. no new values)
:param multiple: whether to allow multiple selections
:param clearable: whether to add a button to clear the selection
:param validation: dictionary of validation rules or a callable that returns an optional error message
:param validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)
:param key_generator: a callback or iterator to generate a dictionary key for new values
"""
self.multiple = multiple
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/textarea.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self,
:param placeholder: text to show if no value is entered
:param value: the initial value of the field
:param on_change: callback to execute when the value changes
:param validation: dictionary of validation rules or a callable that returns an optional error message
:param validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)
"""
super().__init__(label, placeholder=placeholder, value=value, on_change=on_change, validation=validation)
self._props['type'] = 'textarea'
Loading