Skip to content

Commit 37b3efb

Browse files
committed
Merge branch 'master' into split_packages
# Conflicts: # packages/flutter_form_builder/CHANGELOG.md # packages/flutter_form_builder/pubspec.yaml
2 parents 125fb35 + d5de278 commit 37b3efb

File tree

5 files changed

+80
-48
lines changed

5 files changed

+80
-48
lines changed

packages/flutter_form_builder/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
## [7.0.0-alpha.0] - 16-May-2021
1616
* Split up packages - removed fields and validation from core
1717

18+
## [6.2.1] - 27-Oct-2021
19+
* Fixed bug where `didChange` and `reset` on FormBuilderCheckboxGroup has no visible effect
20+
1821
## [6.2.0] - 21-Oct-2021
1922
* Fixed `didChange` unable to handle null value in `FormBuilderTextField`
2023

2124
**BREAKING CHANGE**
2225
* Added new attribute - `autoFocusOnValidationFailure` (default: `false`) - to FormBuilder to set whether should scroll to first error if validation fails
2326

27+
2428
## [6.1.0] - 01-Sep-2021
2529
* When form validation fails, automatically scroll to first error
2630
* New way to programmatically induce custom errors by calling `GlobalKey<FormBuilderState>.invalidateField()` or `GlobalKey<FormBuilderFieldState>.invalidate()`

packages/flutter_form_builder/lib/src/fields/form_builder_date_range_picker.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ class FormBuilderDateRangePickerState
266266
}
267267

268268
@override
269-
void didChange(DateTimeRange? val) {
270-
super.didChange(val);
269+
void didChange(DateTimeRange? value) {
270+
super.didChange(value);
271271
_setTextFieldString();
272272
}
273273

packages/flutter_form_builder/lib/src/widgets/grouped_checkbox.dart

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_form_builder/flutter_form_builder.dart';
33

4-
class GroupedCheckbox<T> extends StatefulWidget {
4+
class GroupedCheckbox<T> extends StatelessWidget {
55
/// A list of string that describes each checkbox. Each item must be distinct.
66
final List<FormBuilderFieldOption<T>> options;
77

@@ -204,38 +204,22 @@ class GroupedCheckbox<T> extends StatefulWidget {
204204
this.controlAffinity = ControlAffinity.leading,
205205
}) : super(key: key);
206206

207-
@override
208-
_GroupedCheckboxState<T> createState() => _GroupedCheckboxState<T>();
209-
}
210-
211-
class _GroupedCheckboxState<T> extends State<GroupedCheckbox<T>> {
212-
final selectedListItems = <T>[];
213-
214-
@override
215-
void initState() {
216-
super.initState();
217-
218-
if (widget.value != null) {
219-
selectedListItems.addAll(widget.value!);
220-
}
221-
}
222-
223207
@override
224208
Widget build(BuildContext context) {
225209
final widgetList = <Widget>[];
226-
for (var i = 0; i < widget.options.length; i++) {
210+
for (var i = 0; i < options.length; i++) {
227211
widgetList.add(item(i));
228212
}
229213
Widget finalWidget;
230-
if (widget.orientation == OptionsOrientation.vertical) {
214+
if (orientation == OptionsOrientation.vertical) {
231215
finalWidget = SingleChildScrollView(
232216
scrollDirection: Axis.vertical,
233217
child: Column(
234218
crossAxisAlignment: CrossAxisAlignment.start,
235219
children: widgetList,
236220
),
237221
);
238-
} else if (widget.orientation == OptionsOrientation.horizontal) {
222+
} else if (orientation == OptionsOrientation.horizontal) {
239223
finalWidget = SingleChildScrollView(
240224
scrollDirection: Axis.horizontal,
241225
child: Row(
@@ -247,14 +231,14 @@ class _GroupedCheckboxState<T> extends State<GroupedCheckbox<T>> {
247231
} else {
248232
finalWidget = SingleChildScrollView(
249233
child: Wrap(
250-
spacing: widget.wrapSpacing,
251-
runSpacing: widget.wrapRunSpacing,
252-
textDirection: widget.wrapTextDirection,
253-
crossAxisAlignment: widget.wrapCrossAxisAlignment,
254-
verticalDirection: widget.wrapVerticalDirection,
255-
alignment: widget.wrapAlignment,
234+
spacing: wrapSpacing,
235+
runSpacing: wrapRunSpacing,
236+
textDirection: wrapTextDirection,
237+
crossAxisAlignment: wrapCrossAxisAlignment,
238+
verticalDirection: wrapVerticalDirection,
239+
alignment: wrapAlignment,
256240
direction: Axis.horizontal,
257-
runAlignment: widget.wrapRunAlignment,
241+
runAlignment: wrapRunAlignment,
258242
children: widgetList,
259243
),
260244
);
@@ -263,50 +247,49 @@ class _GroupedCheckboxState<T> extends State<GroupedCheckbox<T>> {
263247
}
264248

265249
Widget item(int index) {
266-
final option = widget.options[index];
250+
final option = options[index];
267251
final optionValue = option.value;
268-
final isOptionDisabled = true == widget.disabled?.contains(optionValue);
252+
final isOptionDisabled = true == disabled?.contains(optionValue);
269253
final control = Checkbox(
270-
activeColor: widget.activeColor,
271-
checkColor: widget.checkColor,
272-
focusColor: widget.focusColor,
273-
hoverColor: widget.hoverColor,
274-
materialTapTargetSize: widget.materialTapTargetSize,
275-
value: selectedListItems.contains(optionValue),
276-
tristate: widget.tristate,
254+
activeColor: activeColor,
255+
checkColor: checkColor,
256+
focusColor: focusColor,
257+
hoverColor: hoverColor,
258+
materialTapTargetSize: materialTapTargetSize,
259+
value: tristate
260+
? value?.contains(optionValue)
261+
: true == value?.contains(optionValue),
262+
tristate: tristate,
277263
onChanged: isOptionDisabled
278264
? null
279265
: (selected) {
266+
List<T> selectedListItems = value == null ? [] : List.of(value!);
280267
selected!
281268
? selectedListItems.add(optionValue)
282269
: selectedListItems.remove(optionValue);
283-
setState(() {
284-
widget.onChanged(selectedListItems);
285-
});
270+
onChanged(selectedListItems);
286271
},
287272
);
288273
final label = GestureDetector(
289274
onTap: isOptionDisabled
290275
? null
291276
: () {
277+
List<T> selectedListItems = value == null ? [] : List.of(value!);
292278
selectedListItems.contains(optionValue)
293279
? selectedListItems.remove(optionValue)
294280
: selectedListItems.add(optionValue);
295-
setState(() {
296-
widget.onChanged(selectedListItems);
297-
});
281+
onChanged(selectedListItems);
298282
},
299283
child: option,
300284
);
301285

302286
return Row(
303287
mainAxisSize: MainAxisSize.min,
304288
children: <Widget>[
305-
if (widget.controlAffinity == ControlAffinity.leading) control,
289+
if (controlAffinity == ControlAffinity.leading) control,
306290
Flexible(flex: 1, child: label),
307-
if (widget.controlAffinity == ControlAffinity.trailing) control,
308-
if (widget.separator != null && index != widget.options.length - 1)
309-
widget.separator!,
291+
if (controlAffinity == ControlAffinity.trailing) control,
292+
if (separator != null && index != options.length - 1) separator!,
310293
],
311294
);
312295
}

packages/flutter_form_builder/test/form_builder_checkbox_group_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,45 @@ void main() {
2828
expect(formSave(), isTrue);
2929
expect(formValue(widgetName), equals(const [1, 3]));
3030
});
31+
testWidgets('FormBuilderCheckboxGroup -- didChange',
32+
(WidgetTester tester) async {
33+
const fieldName = 'cbg1';
34+
final testWidget = FormBuilderCheckboxGroup<int>(
35+
name: fieldName,
36+
options: const [
37+
FormBuilderFieldOption(key: ValueKey('1'), value: 1),
38+
FormBuilderFieldOption(key: ValueKey('2'), value: 2),
39+
FormBuilderFieldOption(key: ValueKey('3'), value: 3),
40+
],
41+
);
42+
await tester.pumpWidget(buildTestableFieldWidget(testWidget));
43+
44+
expect(formSave(), isTrue);
45+
expect(formValue(fieldName), isNull);
46+
formFieldDidChange(fieldName, [1, 3]);
47+
await tester.pumpAndSettle();
48+
expect(formSave(), isTrue);
49+
expect(formValue(fieldName), [1, 3]);
50+
51+
Checkbox checkbox1 = tester
52+
.element(find.byKey(const ValueKey('1')))
53+
.findAncestorWidgetOfExactType<Row>()!
54+
.children
55+
.first as Checkbox;
56+
Checkbox checkbox2 = tester
57+
.element(find.byKey(const ValueKey('2')))
58+
.findAncestorWidgetOfExactType<Row>()!
59+
.children
60+
.first as Checkbox;
61+
Checkbox checkbox3 = tester
62+
.element(find.byKey(const ValueKey('3')))
63+
.findAncestorWidgetOfExactType<Row>()!
64+
.children
65+
.first as Checkbox;
66+
67+
// checkboxes should represent the state of the didChange value
68+
expect(checkbox1.value, true);
69+
expect(checkbox2.value, false);
70+
expect(checkbox3.value, true);
71+
});
3172
}

packages/flutter_form_builder/test/form_builder_tester.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ Widget buildTestableFieldWidget(Widget widget) {
1515
}
1616

1717
bool formSave() => _formKey.currentState!.saveAndValidate();
18+
void formFieldDidChange(String fieldName, dynamic value) {
19+
_formKey.currentState!.fields[fieldName]!.didChange(value);
20+
}
21+
1822
dynamic formValue(String name) => _formKey.currentState!.value[name];

0 commit comments

Comments
 (0)