Unverified Commit fc870971 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Add Form.onChanged, and rename FormState.onChanged (#15405)

parent aba0379d
......@@ -254,7 +254,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
new Radio<_Location>(
value: _Location.Bahamas,
groupValue: field.value,
onChanged: field.onChanged,
onChanged: field.didChange,
),
const Text('Bahamas')
]
......@@ -265,7 +265,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
new Radio<_Location>(
value: _Location.Barbados,
groupValue: field.value,
onChanged: field.onChanged,
onChanged: field.didChange,
),
const Text('Barbados')
]
......@@ -276,7 +276,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
new Radio<_Location>(
value: _Location.Bermuda,
groupValue: field.value,
onChanged: field.onChanged,
onChanged: field.didChange,
),
const Text('Bermuda')
]
......@@ -320,7 +320,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
activeColor: Colors.orange[100 + (field.value * 5.0).round()],
label: '${field.value.round()}',
value: field.value,
onChanged: field.onChanged,
onChanged: field.didChange,
);
},
),
......
......@@ -98,7 +98,7 @@ class TextFormField extends FormField<String> {
maxLengthEnforced: maxLengthEnforced,
maxLines: maxLines,
maxLength: maxLength,
onChanged: field.onChanged,
onChanged: field.didChange,
onSubmitted: onFieldSubmitted,
inputFormatters: inputFormatters,
);
......@@ -173,6 +173,6 @@ class _TextFormFieldState extends FormFieldState<String> {
// example, the reset() method. In such cases, the FormField value will
// already have been set.
if (_effectiveController.text != value)
onChanged(_effectiveController.text);
didChange(_effectiveController.text);
}
}
......@@ -26,6 +26,7 @@ class Form extends StatefulWidget {
@required this.child,
this.autovalidate: false,
this.onWillPop,
this.onChanged,
}) : assert(child != null),
super(key: key);
......@@ -66,6 +67,12 @@ class Form extends StatefulWidget {
/// back button.
final WillPopCallback onWillPop;
/// Called when one of the form fields changes.
///
/// In addition to this callback being invoked, all the form fields themselves
/// will rebuild.
final VoidCallback onChanged;
@override
FormState createState() => new FormState();
}
......@@ -83,6 +90,12 @@ class FormState extends State<Form> {
// Called when a form field has changed. This will cause all form fields
// to rebuild, useful if form fields have interdependencies.
void _fieldDidChange() {
if (widget.onChanged != null)
widget.onChanged();
_forceRebuild();
}
void _forceRebuild() {
setState(() {
++_generation;
});
......@@ -117,7 +130,12 @@ class FormState extends State<Form> {
}
/// Resets every [FormField] that is a descendant of this [Form] back to its
/// initialState.
/// [FormField.initialState].
///
/// The [Form.onChanged] callback will be called.
///
/// If the form's [Form.autovalidate] property is true, the fields will all be
/// revalidated after being reset.
void reset() {
for (FormFieldState<dynamic> field in _fields)
field.reset();
......@@ -126,8 +144,10 @@ class FormState extends State<Form> {
/// Validates every [FormField] that is a descendant of this [Form], and
/// returns true if there are no errors.
///
/// The form will rebuild to report the results.
bool validate() {
_fieldDidChange();
_forceRebuild();
return _validate();
}
......@@ -213,7 +233,7 @@ class FormField<T> extends StatefulWidget {
super(key: key);
/// An optional method to call with the final value when the form is saved via
/// Form.save().
/// [FormState.save].
final FormFieldSetter<T> onSaved;
/// An optional method that validates an input. Returns an error string to
......@@ -289,8 +309,11 @@ class FormFieldState<T> extends State<FormField<T>> {
}
/// Updates this field's state to the new value. Useful for responding to
/// child widget changes, e.g. [Slider]'s onChanged argument.
void onChanged(T value) {
/// child widget changes, e.g. [Slider]'s [Slider.onChanged] argument.
///
/// Triggers the [Form.onChanged] callback and, if the [Form.autovalidate]
/// field is set, revalidates all the fields of the form.
void didChange(T value) {
setState(() {
_value = value;
});
......@@ -302,7 +325,7 @@ class FormFieldState<T> extends State<FormField<T>> {
/// This method should be only be called by subclasses that need to update
/// the form field value due to state changes identified during the widget
/// build phase, when calling `setState` is prohibited. In all other cases,
/// the value should be set by a call to [onChanged], which ensures that
/// the value should be set by a call to [didChange], which ensures that
/// `setState` is called.
@protected
void setValue(T value) {
......
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