mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
![]() Introducing the `forceErrorText` property to both `FormField` and `TextFormField`. With this addition, we gain the capability to trigger an error state and provide an error message without invoking the `validator` method. While the idea of making the `Validator` method work asynchronously may be appealing, it could introduce significant complexity to our current form field implementation. Additionally, this approach might not be suitable for all developers, as discussed by @justinmc in this [comment](https://github.com/flutter/flutter/issues/56414#issuecomment-624960263). This PR try to address this issue by adding `forceErrorText` property allowing us to force the error to the `FormField` or `TextFormField` at our own base making it possible to preform some async operations without the need for any hacks while keep the ability to check for errors if we call `formKey.currentState!.validate()`. Here is an example: <details> <summary>Code Example</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp( const MaterialApp(home: MyHomePage()), ); } class MyHomePage extends StatefulWidget { const MyHomePage({ super.key, }); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final key = GlobalKey<FormState>(); String? forcedErrorText; Future<void> handleValidation() async { // simulate some async work.. await Future.delayed(const Duration(seconds: 3)); setState(() { forcedErrorText = 'this username is not available.'; }); // wait for build to run and then check. // // this is not required though, as the error would already be showing. WidgetsBinding.instance.addPostFrameCallback((_) { print(key.currentState!.validate()); }); } @override Widget build(BuildContext context) { print('build'); return Scaffold( floatingActionButton: FloatingActionButton(onPressed: handleValidation), body: Form( key: key, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: TextFormField( forceErrorText: forcedErrorText, ), ), ], ), ), ), ); } } ``` </details> Related to #9688 & #56414. Happy to hear your thoughts on this. |
||
---|---|---|
.. | ||
about | ||
action_buttons | ||
action_chip | ||
animated_icon | ||
app | ||
app_bar | ||
autocomplete | ||
badge | ||
banner | ||
bottom_app_bar | ||
bottom_navigation_bar | ||
bottom_sheet | ||
button_style | ||
button_style_button | ||
card | ||
carousel | ||
checkbox | ||
checkbox_list_tile | ||
chip | ||
choice_chip | ||
color_scheme | ||
context_menu | ||
data_table | ||
date_picker | ||
dialog | ||
divider | ||
drawer | ||
dropdown | ||
dropdown_menu | ||
elevated_button | ||
expansion_panel | ||
expansion_tile | ||
filled_button | ||
filter_chip | ||
flexible_space_bar | ||
floating_action_button | ||
floating_action_button_location | ||
icon_button | ||
ink | ||
ink_well | ||
input_chip | ||
input_decorator | ||
list_tile | ||
material_state | ||
menu_anchor | ||
navigation_bar | ||
navigation_drawer | ||
navigation_rail | ||
outlined_button | ||
page_transitions_theme | ||
paginated_data_table | ||
platform_menu_bar | ||
popup_menu | ||
progress_indicator | ||
radio | ||
radio_list_tile | ||
range_slider | ||
refresh_indicator | ||
reorderable_list | ||
scaffold | ||
scrollbar | ||
search_anchor | ||
segmented_button | ||
selectable_region | ||
selection_area | ||
selection_container | ||
slider | ||
snack_bar | ||
stepper | ||
switch | ||
switch_list_tile | ||
tab_controller | ||
tabs | ||
text_button | ||
text_field | ||
text_form_field | ||
theme | ||
theme_data | ||
time_picker | ||
toggle_buttons | ||
tooltip |