@@ -65,9 +65,13 @@ def _build_form(self):
6565 assert "type" in field
6666 assert "label" in field
6767 label = field ["label" ]
68- row , widget = self ._create_field (label , field )
68+ row , widget , label_widget = self ._create_field (label , field )
6969 if widget :
70- self .fields [field .get ("id" )] = {"widget" : widget , "config" : field }
70+ self .fields [field .get ("id" )] = {
71+ "widget" : widget ,
72+ "label_widget" : label_widget ,
73+ "config" : field ,
74+ }
7175 self .form_container .append (row )
7276 elif row :
7377 self .form_container .append (row )
@@ -102,7 +106,7 @@ def _create_field(self, label_text: str, field: dict):
102106 elif field_type == "radio" :
103107 options = field .get ("options" )
104108 if not options :
105- return None , None
109+ return None , None , label
106110 widget = []
107111 first_radio = None
108112 for option in options :
@@ -123,7 +127,7 @@ def _create_field(self, label_text: str, field: dict):
123127 widget .remove_css_class ("view" )
124128 row .append (widget )
125129 elif field_type == "label" :
126- return row , None
130+ return row , None , label
127131 elif field_type == "picture" :
128132 try :
129133 file = Gio .File .new_for_uri (field .get ("uri" , None ))
@@ -139,14 +143,14 @@ def _create_field(self, label_text: str, field: dict):
139143 widget .set_margin_top (10 )
140144 widget .set_margin_bottom (10 )
141145 row .append (widget )
142- return row , None
146+ return row , None , label
143147 except Exception as _e :
144148 toast = Adw .Toast (
145149 f"Error in opening picture at { field .get ('uri' , None )} "
146150 )
147151 toast .set_timeout (4 )
148152 self .form_toast_overlay .add_toast (toast )
149- return None , None
153+ return None , None , label
150154
151155 elif field_type == "calendar" :
152156 widget = Gtk .Calendar ()
@@ -162,13 +166,13 @@ def _create_field(self, label_text: str, field: dict):
162166 widget = Gtk .SpinButton ()
163167 row .append (widget )
164168 else :
165- return None , None
169+ return None , None , label
166170
167171 style_list = field .get ("style" , [])
168172 for style in style_list :
169173 label .add_css_class (style )
170174
171- return row , widget
175+ return row , widget , label
172176
173177 @Gtk .Template .Callback ()
174178 def on_submit_clicked (self , * _ ):
@@ -187,49 +191,69 @@ def _collect_data(self) -> dict:
187191
188192 for field_id , field_dict in self .fields .items ():
189193 widget = field_dict ["widget" ]
190- field_value = None
191- if isinstance (widget , Gtk .Entry ):
192- field_value = widget .get_text ()
193- elif isinstance (widget , Gtk .TextView ):
194- text_buffer = widget .get_buffer ()
195- start_iter = text_buffer .get_start_iter ()
196- end_iter = text_buffer .get_end_iter ()
197- field_value = text_buffer .get_text (start_iter , end_iter , True )
198- elif isinstance (widget , list ):
199- for indv_widget in widget :
200- active = indv_widget .get_active ()
201- if active :
202- field_value = indv_widget .get_label ()
203- elif isinstance (widget , Gtk .CheckButton ):
204- active = widget .get_active ()
205- field_value = True if active else False
206- elif isinstance (widget , Gtk .Calendar ):
207- date = widget .get_date ().format_iso8601 ()
208- field_value = date
209- elif isinstance (widget , Gtk .SpinButton ):
210- field_value = widget .get_value_as_int ()
211- field_dict_config = field_dict .get ("config" , None )
212- if not field_dict_config :
194+ field_value = self .get_value_from_field (widget )
195+ if field_dict .get ("config" , None ) is None :
213196 show_fatal_toast (self .form_toast_overlay )
214- if field_dict_config .get ("required" , False ):
215- show_toast = False
216- if field_value is None :
217- show_toast = True
218- if isinstance (field_value , str ) and field_value == "" :
219- show_toast = True
220- if isinstance (field_value , bool ) and not field_value :
221- show_toast = True
222- if show_toast :
223- toast = Adw .Toast .new (
224- f"Please fill the required field: { field_dict_config .get ('label' , 'All' )} "
225- )
226- toast .set_timeout (2 )
227- self .form_toast_overlay .add_toast (toast )
228- return None
197+ return None
198+ validate_result = self .validate_field_value (widget , field_dict , field_value )
199+ if validate_result is None or not validate_result :
200+ return None
229201 data [field_id ] = field_value
230202
231203 return data
232204
205+ def get_value_from_field (self , widget ):
206+ field_value = None
207+ if isinstance (widget , Gtk .Entry ):
208+ field_value = widget .get_text ()
209+ elif isinstance (widget , Gtk .TextView ):
210+ text_buffer = widget .get_buffer ()
211+ start_iter = text_buffer .get_start_iter ()
212+ end_iter = text_buffer .get_end_iter ()
213+ field_value = text_buffer .get_text (start_iter , end_iter , True )
214+ elif isinstance (widget , list ):
215+ for indv_widget in widget :
216+ active = indv_widget .get_active ()
217+ if active :
218+ field_value = indv_widget .get_label ()
219+ elif isinstance (widget , Gtk .CheckButton ):
220+ active = widget .get_active ()
221+ field_value = True if active else False
222+ elif isinstance (widget , Gtk .Calendar ):
223+ date = widget .get_date ().format_iso8601 ()
224+ field_value = date
225+ elif isinstance (widget , Gtk .SpinButton ):
226+ field_value = widget .get_value_as_int ()
227+
228+ return field_value
229+
230+ def validate_field_value (self , widget , field_dict , field_value ):
231+ field_dict_config = field_dict .get ("config" , None )
232+ if field_dict_config .get ("required" , False ):
233+ show_toast = False
234+ if field_value is None :
235+ show_toast = True
236+ if isinstance (field_value , str ) and field_value == "" :
237+ show_toast = True
238+ if isinstance (field_value , bool ) and not field_value :
239+ show_toast = True
240+ if show_toast :
241+ toast = Adw .Toast .new (
242+ f"Please fill the required field: { field_dict_config .get ('label' , 'All' )} "
243+ )
244+ toast .set_timeout (2 )
245+ self .form_toast_overlay .add_toast (toast )
246+ if field_dict_config .get ("type" , None ) == "check" :
247+ widget .add_css_class ("error" )
248+ else :
249+ field_dict ["label_widget" ].add_css_class ("error" )
250+ return False
251+ if field_dict_config .get ("type" , None ) == "check" :
252+ widget .remove_css_class ("error" )
253+ else :
254+ field_dict ["label_widget" ].remove_css_class ("error" )
255+ return True
256+
233257 def _append_to_csv (self , data : dict ):
234258 if self .page is None :
235259 show_fatal_toast (self .form_toast_overlay )
0 commit comments