Unverified Commit 949023b2 authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Add Form.onSaved (#30643)

When submitting data to a server, callers need a callback that will
get invoked after all the individual form fields are saved. If they
have a button that submits the form, they could just do this logic
in the click handler for the button (save the form, then submit to
the server), but if they have more ways than one to submit the form
(i.e. hitting enter while in a text form field), then it becomes
more convoluted and calls for a unified callback that will get
notified when the form is submitted.
parent cb78274c
......@@ -72,6 +72,7 @@ class Form extends StatefulWidget {
this.autovalidate = false,
this.onWillPop,
this.onChanged,
this.onSaved,
}) : assert(child != null),
super(key: key);
......@@ -118,6 +119,13 @@ class Form extends StatefulWidget {
/// will rebuild.
final VoidCallback onChanged;
/// Called when the form is saved (after all the form fields have been saved).
///
/// See also:
///
/// * [FormState.save]
final VoidCallback onSaved;
@override
FormState createState() => FormState();
}
......@@ -172,6 +180,8 @@ class FormState extends State<Form> {
void save() {
for (FormFieldState<dynamic> field in _fields)
field.save();
if (widget.onSaved != null)
widget.onSaved();
}
/// Resets every [FormField] that is a descendant of this [Form] back to its
......
......@@ -6,9 +6,10 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
void main() {
testWidgets('onSaved callback is called', (WidgetTester tester) async {
testWidgets('onSaved callbacks are called', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
String fieldValue;
bool fieldModifiedSinceFormOnSaved;
Widget builder() {
return MediaQuery(
......@@ -19,8 +20,12 @@ void main() {
child: Material(
child: Form(
key: formKey,
onSaved: () { fieldModifiedSinceFormOnSaved = false; },
child: TextFormField(
onSaved: (String value) { fieldValue = value; },
onSaved: (String value) {
fieldValue = value;
fieldModifiedSinceFormOnSaved = true;
},
),
),
),
......@@ -38,6 +43,7 @@ void main() {
formKey.currentState.save();
// pump'ing is unnecessary because callback happens regardless of frames
expect(fieldValue, equals(testValue));
expect(fieldModifiedSinceFormOnSaved, isFalse);
}
await checkText('Test');
......
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