Skip to content

Commit

Permalink
fix: Display informative message when date has wrong format (#4019)
Browse files Browse the repository at this point in the history
* datetime utils

* wrap datetime parsing in a try-catch

* update datetime setters to use new util

* remove str from datetime typing

* fix import errors

* remove datetime_to_string

* datetime props accept only datetime objects (strict mode)

---------

Co-authored-by: Feodor Fitsner <[email protected]>
  • Loading branch information
ndonkoHenri and FeodorFitsner authored Nov 8, 2024
1 parent 95e679f commit 26ed9dd
Showing 6 changed files with 98 additions and 95 deletions.
6 changes: 5 additions & 1 deletion packages/flet/lib/src/models/control.dart
Original file line number Diff line number Diff line change
@@ -102,7 +102,11 @@ class Control extends Equatable {
if (value == null) {
return defValue;
}
return DateTime.parse(value);
try {
return DateTime.parse(value);
} catch (e) {
return null;
}
}

TimeOfDay? attrTime(String name, [TimeOfDay? defValue]) {
11 changes: 6 additions & 5 deletions sdk/python/packages/flet/src/flet/core/alert_dialog.py
Original file line number Diff line number Diff line change
@@ -93,6 +93,7 @@ def __init__(
title_text_style: Optional[TextStyle] = None,
clip_behavior: Optional[ClipBehavior] = None,
semantics_label: Optional[str] = None,
barrier_color: Optional[ColorValue] = None,
on_dismiss: OptionalControlEventCallable = None,
#
# AdaptiveControl
@@ -102,7 +103,6 @@ def __init__(
visible: Optional[bool] = None,
data: Any = None,
adaptive: Optional[bool] = None,
barrier_color: Optional[str] = None
):
Control.__init__(
self,
@@ -211,12 +211,13 @@ def shadow_color(self, value: Optional[ColorValue]):

# barrier_color
@property
def barrier_color(self) -> Optional[str]:
return self._get_attr("barrierColor")
def barrier_color(self) -> Optional[ColorValue]:
return self.__barrier_color

@barrier_color.setter
def barrier_color(self, value: Optional[str]):
self._set_attr("barrierColor", value)
def barrier_color(self, value: Optional[ColorValue]):
self.__barrier_color = value
self._set_enum_attr("barrierColor", value, ColorEnums)

# surface_tint_color
@property
30 changes: 15 additions & 15 deletions sdk/python/packages/flet/src/flet/core/cupertino_date_picker.py
Original file line number Diff line number Diff line change
@@ -138,42 +138,42 @@ def _get_control_name(self):
# value
@property
def value(self) -> Optional[datetime]:
value_string = self._get_attr("value", def_value=None)
value_string = self._get_attr("value")
return datetime.fromisoformat(value_string) if value_string else None

@value.setter
def value(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("value", value)
def value(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("value must be of type date, datetime or None")
self._set_attr("value", value.isoformat())

# first_date
@property
def first_date(self) -> Optional[datetime]:
value_string = self._get_attr("firstDate", def_value=None)
value_string = self._get_attr("firstDate")
return (
datetime.fromisoformat(value_string) if value_string is not None else None
)

@first_date.setter
def first_date(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("firstDate", value)
def first_date(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("first_date must be of type date, datetime or None")
self._set_attr("firstDate", value.isoformat())

# last_date
@property
def last_date(self) -> Optional[datetime]:
value_string = self._get_attr("lastDate", def_value=None)
value_string = self._get_attr("lastDate")
return (
datetime.fromisoformat(value_string) if value_string is not None else None
)

@last_date.setter
def last_date(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("lastDate", value)
def last_date(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("last_date must be of type date, datetime or None")
self._set_attr("lastDate", value.isoformat())

# bgcolor
@property
85 changes: 41 additions & 44 deletions sdk/python/packages/flet/src/flet/core/date_picker.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@
from flet.core.textfield import KeyboardType
from flet.core.tooltip import TooltipValue
from flet.core.types import (
ColorEnums,
ColorValue,
IconEnums,
IconValue,
OptionalControlEventCallable,
@@ -106,6 +108,7 @@ def __init__(
field_label_text: Optional[str] = None,
switch_to_calendar_icon: Optional[IconValue] = None,
switch_to_input_icon: Optional[IconValue] = None,
barrier_color: Optional[ColorValue] = None,
on_change: OptionalControlEventCallable = None,
on_dismiss: OptionalControlEventCallable = None,
on_entry_mode_change: OptionalEventCallable[
@@ -124,7 +127,6 @@ def __init__(
visible: Optional[bool] = None,
disabled: Optional[bool] = None,
data: Any = None,
barrier_color: Optional[str] = None
):
Control.__init__(
self,
@@ -204,61 +206,55 @@ def open(self, value: Optional[bool]):
# value
@property
def value(self) -> Optional[datetime]:
value_string = self._get_attr("value", def_value=None)
return datetime.fromisoformat(value_string) if value_string else None
v = self._get_attr("value")
return datetime.fromisoformat(v) if v else None

@value.setter
def value(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("value", value)
def value(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("value must be of type date, datetime or None")
self._set_attr("value", value.isoformat())

# first_date
@property
def first_date(self) -> Optional[datetime]:
value_string = self._get_attr("firstDate", def_value=None)
return (
datetime.fromisoformat(value_string) if value_string is not None else None
)
v = self._get_attr("firstDate")
return datetime.fromisoformat(v) if v is not None else None

@first_date.setter
def first_date(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("firstDate", value)
def first_date(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("first_date must be of type date, datetime or None")
self._set_attr("firstDate", value.isoformat())

# last_date
@property
def last_date(self) -> Optional[datetime]:
value_string = self._get_attr("lastDate", def_value=None)
return (
datetime.fromisoformat(value_string) if value_string is not None else None
)
v = self._get_attr("lastDate")
return datetime.fromisoformat(v) if v is not None else None

@last_date.setter
def last_date(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("lastDate", value)
def last_date(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("last_date must be of type date, datetime or None")
self._set_attr("lastDate", value.isoformat())

# current_date
@property
def current_date(self) -> Optional[datetime]:
value_string = self._get_attr("currentDate", def_value=None)
return (
datetime.fromisoformat(value_string) if value_string is not None else None
)
v = self._get_attr("currentDate")
return datetime.fromisoformat(v) if v is not None else None

@current_date.setter
def current_date(self, value: Optional[Union[datetime, str]]):
if isinstance(value, (date, datetime)):
value = value.isoformat()
self._set_attr("currentDate", value)
def current_date(self, value: Optional[Union[date, datetime]]):
if not isinstance(value, (date, datetime)):
raise ValueError("current_date must be of type date, datetime or None")
self._set_attr("currentDate", value.isoformat())

# field_hint_text
@property
def field_hint_text(self) -> Optional[str]:
return self._get_attr("fieldHintText", def_value=None)
return self._get_attr("fieldHintText")

@field_hint_text.setter
def field_hint_text(self, value: Optional[str]):
@@ -267,7 +263,7 @@ def field_hint_text(self, value: Optional[str]):
# field_label_text
@property
def field_label_text(self) -> Optional[str]:
return self._get_attr("fieldLabelText", def_value=None)
return self._get_attr("fieldLabelText")

@field_label_text.setter
def field_label_text(self, value: Optional[str]):
@@ -276,7 +272,7 @@ def field_label_text(self, value: Optional[str]):
# help_text
@property
def help_text(self) -> Optional[str]:
return self._get_attr("helpText", def_value=None)
return self._get_attr("helpText")

@help_text.setter
def help_text(self, value: Optional[str]):
@@ -285,7 +281,7 @@ def help_text(self, value: Optional[str]):
# cancel_text
@property
def cancel_text(self) -> Optional[str]:
return self._get_attr("cancelText", def_value=None)
return self._get_attr("cancelText")

@cancel_text.setter
def cancel_text(self, value: Optional[str]):
@@ -294,7 +290,7 @@ def cancel_text(self, value: Optional[str]):
# confirm_text
@property
def confirm_text(self) -> Optional[str]:
return self._get_attr("confirmText", def_value=None)
return self._get_attr("confirmText")

@confirm_text.setter
def confirm_text(self, value: Optional[str]):
@@ -303,7 +299,7 @@ def confirm_text(self, value: Optional[str]):
# error_format_text
@property
def error_format_text(self) -> Optional[str]:
return self._get_attr("errorFormatText", def_value=None)
return self._get_attr("errorFormatText")

@error_format_text.setter
def error_format_text(self, value: Optional[str]):
@@ -312,7 +308,7 @@ def error_format_text(self, value: Optional[str]):
# error_invalid_text
@property
def error_invalid_text(self) -> Optional[str]:
return self._get_attr("errorInvalidText", def_value=None)
return self._get_attr("errorInvalidText")

@error_invalid_text.setter
def error_invalid_text(self, value: Optional[str]):
@@ -398,12 +394,13 @@ def on_entry_mode_change(
self, handler: OptionalEventCallable[DatePickerEntryModeChangeEvent]
):
self.__on_entry_mode_change.handler = handler
#barrier_color

# barrier_color
@property
def barrier_color(self) -> Optional[str]:
return self._get_attr("barrierColor")
def barrier_color(self) -> Optional[ColorValue]:
return self.__barrier_color

@barrier_color.setter
def barrier_color(self, value: Optional[str]):
self._set_attr("barrierColor", value)
def barrier_color(self, value: Optional[ColorValue]):
self.__barrier_color = value
self._set_enum_attr("barrierColor", value, ColorEnums)
25 changes: 13 additions & 12 deletions sdk/python/packages/flet/src/flet/core/time_picker.py
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
from flet.core.ref import Ref
from flet.core.tooltip import TooltipValue
from flet.core.types import (
ColorEnums,
ColorValue,
OptionalControlEventCallable,
OptionalEventCallable,
Orientation,
@@ -93,6 +95,7 @@ def __init__(
confirm_text: Optional[str] = None,
error_invalid_text: Optional[str] = None,
orientation: Optional[Orientation] = None,
barrier_color: Optional[ColorValue] = None,
on_change: OptionalControlEventCallable = None,
on_dismiss: OptionalControlEventCallable = None,
on_entry_mode_change: OptionalEventCallable[
@@ -111,7 +114,6 @@ def __init__(
visible: Optional[bool] = None,
disabled: Optional[bool] = None,
data: Any = None,
barrier_color: Optional[str] = None
):
Control.__init__(
self,
@@ -147,7 +149,7 @@ def __init__(
self.on_dismiss = on_dismiss
self.open = open
self.on_entry_mode_change = on_entry_mode_change
self.barrier_color=barrier_color
self.barrier_color = barrier_color

def _get_control_name(self):
return "timepicker"
@@ -181,11 +183,9 @@ def open(self, value: Optional[bool]):
# value
@property
def value(self) -> Optional[time]:
value_string = self._get_attr(
"value", def_value=None
) # value_string in comes in format 'HH:MM'
value_string = self._get_attr("value", def_value=None)
if value_string:
splitted = value_string.split(":")
splitted = value_string.split(":") # value_string comes in format 'HH:MM'
return time(hour=int(splitted[0]), minute=int(splitted[1]))
else:
return None
@@ -300,12 +300,13 @@ def on_entry_mode_change(
self, handler: OptionalEventCallable[TimePickerEntryModeChangeEvent]
):
self.__on_entry_mode_change.handler = handler
#barrier_color

# barrier_color
@property
def barrier_color(self) -> Optional[str]:
return self._get_attr("barrierColor")
def barrier_color(self) -> Optional[ColorValue]:
return self.__barrier_color

@barrier_color.setter
def barrier_color(self, value: Optional[str]):
self._set_attr("barrierColor", value)
def barrier_color(self, value: Optional[ColorValue]):
self.__barrier_color = value
self._set_enum_attr("barrierColor", value, ColorEnums)
Loading

0 comments on commit 26ed9dd

Please sign in to comment.