Unverified Commit e7c90057 authored by Tjong Anthony's avatar Tjong Anthony Committed by GitHub

[Form] Add is valid to FormState (#48948)

parent 4c5aef63
......@@ -349,6 +349,16 @@ class FormFieldState<T> extends State<FormField<T>> {
/// True if this field has any validation errors.
bool get hasError => _errorText != null;
/// True if the current value is valid.
///
/// This will not set [errorText] or [hasError] and it will not update
/// error display.
///
/// See also:
///
/// * [validate], which may update [errorText] and [hasError].
bool get isValid => widget.validator?.call(_value) == null;
/// Calls the [FormField]'s onSaved method with the current value.
void save() {
if (widget.onSaved != null)
......@@ -365,6 +375,11 @@ class FormFieldState<T> extends State<FormField<T>> {
/// Calls [FormField.validator] to set the [errorText]. Returns true if there
/// were no errors.
///
/// See also:
///
/// * [isValid], which passively gets the validity without setting
/// [errorText] or [hasError].
bool validate() {
setState(() {
_validate();
......
......@@ -137,6 +137,100 @@ void main() {
await checkErrorText('');
});
testWidgets('isValid returns true when a field is valid', (WidgetTester tester) async {
final GlobalKey<FormFieldState<String>> fieldKey1 = GlobalKey<FormFieldState<String>>();
final GlobalKey<FormFieldState<String>> fieldKey2 = GlobalKey<FormFieldState<String>>();
const String validString = 'Valid string';
String validator(String s) => s == validString ? null : 'Error text';
Widget builder() {
return MaterialApp(
home: MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: Form(
child: ListView(
children: <Widget>[
TextFormField(
key: fieldKey1,
initialValue: validString,
validator: validator,
autovalidate: true
),
TextFormField(
key: fieldKey2,
initialValue: validString,
validator: validator,
autovalidate: true
),
],
),
),
),
),
),
),
);
}
await tester.pumpWidget(builder());
expect(fieldKey1.currentState.isValid, isTrue);
expect(fieldKey2.currentState.isValid, isTrue);
});
testWidgets(
'isValid returns false when the field is invalid and does not change error display',
(WidgetTester tester) async {
final GlobalKey<FormFieldState<String>> fieldKey1 = GlobalKey<FormFieldState<String>>();
final GlobalKey<FormFieldState<String>> fieldKey2 = GlobalKey<FormFieldState<String>>();
const String validString = 'Valid string';
String validator(String s) => s == validString ? null : 'Error text';
Widget builder() {
return MaterialApp(
home: MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: Form(
child: ListView(
children: <Widget>[
TextFormField(
key: fieldKey1,
initialValue: validString,
validator: validator,
autovalidate: false,
),
TextFormField(
key: fieldKey2,
initialValue: '',
validator: validator,
autovalidate: false,
),
],
),
),
),
),
),
),
);
}
await tester.pumpWidget(builder());
expect(fieldKey1.currentState.isValid, isTrue);
expect(fieldKey2.currentState.isValid, isFalse);
expect(fieldKey2.currentState.hasError, isFalse);
},
);
testWidgets('Multiple TextFormFields communicate', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final GlobalKey<FormFieldState<String>> fieldKey = GlobalKey<FormFieldState<String>>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment