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