Skip to content

Commit c945500

Browse files
committed
fix(core): FormBuilder.onChanged during setInternalFieldValue instead of as Form widget attribute. Fixes #960
avoids calling onChanged before internal changes are done
1 parent cdd449f commit c945500

File tree

3 files changed

+13
-22
lines changed

3 files changed

+13
-22
lines changed

packages/flutter_form_builder/example/lib/main.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class CompleteFormState extends State<CompleteForm> {
5858
FormBuilder(
5959
key: _formKey,
6060
// enabled: false,
61+
onChanged: () {
62+
_formKey.currentState!.save();
63+
debugPrint(_formKey.currentState!.value.toString());
64+
},
6165
autovalidateMode: AutovalidateMode.disabled,
6266
initialValue: const {
6367
'movie_rating': 5,

packages/flutter_form_builder/lib/src/form_builder.dart

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import 'dart:developer';
22

33
import 'package:flutter/material.dart';
4-
54
import 'package:flutter_form_builder/flutter_form_builder.dart';
65

76
/// A container for form fields.
@@ -126,15 +125,13 @@ class FormBuilderState extends State<FormBuilder> {
126125
initialValue[name];
127126
}
128127

129-
void setInternalFieldValue<T>(
130-
String name,
131-
T? value, {
132-
required bool isSetState,
133-
}) {
128+
void setInternalFieldValue<T>(String name, T? value,
129+
{required bool isSetState}) {
134130
_instantValue[name] = value;
135131
if (isSetState) {
136132
setState(() {});
137133
}
134+
widget.onChanged?.call();
138135
}
139136

140137
bool get isValid =>
@@ -170,10 +167,7 @@ class FormBuilderState extends State<FormBuilder> {
170167
field.registerTransformer(_transformers);
171168
if (oldField != null) {
172169
// ignore: invalid_use_of_protected_member
173-
field.setValue(
174-
oldField.value,
175-
populateForm: false,
176-
);
170+
field.setValue(oldField.value, populateForm: false);
177171
} else {
178172
// ignore: invalid_use_of_protected_member
179173
field.setValue(
@@ -263,7 +257,7 @@ class FormBuilderState extends State<FormBuilder> {
263257
key: _formKey,
264258
autovalidateMode: widget.autovalidateMode,
265259
onWillPop: widget.onWillPop,
266-
onChanged: widget.onChanged,
260+
// `onChanged` is called during setInternalFieldValue else will be called early
267261
child: FocusTraversalGroup(
268262
policy: WidgetOrderTraversalPolicy(),
269263
child: widget.child,

packages/flutter_form_builder/lib/src/form_builder_field.dart

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:flutter/material.dart';
2-
32
import 'package:flutter_form_builder/flutter_form_builder.dart';
43

54
enum OptionsOrientation { horizontal, vertical, wrap }
@@ -47,7 +46,7 @@ class FormBuilderField<T> extends FormField<T> {
4746
/// {@macro flutter.widgets.Focus.focusNode}
4847
final FocusNode? focusNode;
4948

50-
//TODO: implement bool autofocus, ValueChanged<bool> onValidated
49+
// TODO: implement bool autofocus, ValueChanged<bool> onValidated
5150

5251
/// Creates a single form field.
5352
const FormBuilderField({
@@ -167,9 +166,7 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
167166
// super.save();
168167
// }
169168

170-
void _informFormForFieldChange({
171-
required bool isSetState,
172-
}) {
169+
void _informFormForFieldChange({required bool isSetState}) {
173170
if (_formBuilderState != null) {
174171
if (enabled || !_formBuilderState!.widget.skipDisabled) {
175172
_formBuilderState!.setInternalFieldValue<T>(
@@ -196,18 +193,14 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
196193
void setValue(T? value, {bool populateForm = true}) {
197194
super.setValue(value);
198195
if (populateForm) {
199-
_informFormForFieldChange(
200-
isSetState: false,
201-
);
196+
_informFormForFieldChange(isSetState: false);
202197
}
203198
}
204199

205200
@override
206201
void didChange(T? value) {
207202
super.didChange(value);
208-
_informFormForFieldChange(
209-
isSetState: false,
210-
);
203+
_informFormForFieldChange(isSetState: false);
211204
widget.onChanged?.call(value);
212205
}
213206

0 commit comments

Comments
 (0)