Fix disabled formfield validation (#23167)
* Fix form field validate method being called if form field is disabled
diff --git a/packages/flutter/lib/src/material/text_form_field.dart b/packages/flutter/lib/src/material/text_form_field.dart
index df4d79f..bf2834a 100644
--- a/packages/flutter/lib/src/material/text_form_field.dart
+++ b/packages/flutter/lib/src/material/text_form_field.dart
@@ -71,7 +71,7 @@
FormFieldSetter<String> onSaved,
FormFieldValidator<String> validator,
List<TextInputFormatter> inputFormatters,
- bool enabled,
+ bool enabled = true,
Brightness keyboardAppearance,
EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
}) : assert(initialValue == null || controller == null),
@@ -90,6 +90,7 @@
onSaved: onSaved,
validator: validator,
autovalidate: autovalidate,
+ enabled: enabled,
builder: (FormFieldState<String> field) {
final _TextFormFieldState state = field;
final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
diff --git a/packages/flutter/lib/src/widgets/form.dart b/packages/flutter/lib/src/widgets/form.dart
index ff0d5da..b34d974 100644
--- a/packages/flutter/lib/src/widgets/form.dart
+++ b/packages/flutter/lib/src/widgets/form.dart
@@ -227,6 +227,7 @@
this.validator,
this.initialValue,
this.autovalidate = false,
+ this.enabled = true,
}) : assert(builder != null),
super(key: key);
@@ -256,6 +257,13 @@
/// autovalidates, this value will be ignored.
final bool autovalidate;
+ /// Whether the form is able to receive user input.
+ ///
+ /// Defaults to true. If [autovalidate] is true, the field will be validated.
+ /// Likewise, if this field is false, the widget will not be validated
+ /// regardless of [autovalidate].
+ final bool enabled;
+
@override
FormFieldState<T> createState() => FormFieldState<T>();
}
@@ -344,7 +352,8 @@
@override
Widget build(BuildContext context) {
- if (widget.autovalidate)
+ // Only autovalidate if the widget is also enabled
+ if (widget.autovalidate && widget.enabled)
_validate();
Form.of(context)?._register(this);
return widget.builder(this);
diff --git a/packages/flutter/test/material/text_form_field_test.dart b/packages/flutter/test/material/text_form_field_test.dart
index b80e155..4ad6c40 100644
--- a/packages/flutter/test/material/text_form_field_test.dart
+++ b/packages/flutter/test/material/text_form_field_test.dart
@@ -114,4 +114,52 @@
await tester.pump();
expect(_validateCalled, 2);
});
+
+ testWidgets('validate is not called if widget is disabled', (WidgetTester tester) async {
+ int _validateCalled = 0;
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: Center(
+ child: TextFormField(
+ enabled: false,
+ autovalidate: true,
+ validator: (String value) { _validateCalled += 1; return null; },
+ ),
+ ),
+ ),
+ ),
+ );
+
+ expect(_validateCalled, 0);
+ await tester.showKeyboard(find.byType(TextField));
+ await tester.enterText(find.byType(TextField), 'a');
+ await tester.pump();
+ expect(_validateCalled, 0);
+ });
+
+ testWidgets('validate is called if widget is enabled', (WidgetTester tester) async {
+ int _validateCalled = 0;
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: Center(
+ child: TextFormField(
+ enabled: true,
+ autovalidate: true,
+ validator: (String value) { _validateCalled += 1; return null; },
+ ),
+ ),
+ ),
+ ),
+ );
+
+ expect(_validateCalled, 1);
+ await tester.showKeyboard(find.byType(TextField));
+ await tester.enterText(find.byType(TextField), 'a');
+ await tester.pump();
+ expect(_validateCalled, 2);
+ });
}