Skip to content

Commit 27366d5

Browse files
Merge pull request #1239 from flutter-form-builder-ecosystem/fix-687
Fix 687 and 1231
2 parents c48671f + f7965e0 commit 27366d5

File tree

3 files changed

+169
-41
lines changed

3 files changed

+169
-41
lines changed

example/lib/main.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:example/sources/conditional_fields.dart';
22
import 'package:example/sources/dynamic_fields.dart';
3+
import 'package:example/sources/related_fields.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter_localizations/flutter_localizations.dart';
56
import 'package:form_builder_validators/form_builder_validators.dart';
@@ -123,6 +124,23 @@ class _HomePage extends StatelessWidget {
123124
);
124125
},
125126
),
127+
const Divider(),
128+
ListTile(
129+
title: const Text('Related Fields'),
130+
trailing: const Icon(Icons.arrow_right_sharp),
131+
onTap: () {
132+
Navigator.of(context).push(
133+
MaterialPageRoute(
134+
builder: (context) {
135+
return const CodePage(
136+
title: 'Related Fields',
137+
child: RelatedFields(),
138+
);
139+
},
140+
),
141+
);
142+
},
143+
),
126144
],
127145
),
128146
);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_form_builder/flutter_form_builder.dart';
3+
4+
class RelatedFields extends StatefulWidget {
5+
const RelatedFields({Key? key}) : super(key: key);
6+
7+
@override
8+
State<RelatedFields> createState() => _RelatedFieldsState();
9+
}
10+
11+
class _RelatedFieldsState extends State<RelatedFields> {
12+
final _formKey = GlobalKey<FormBuilderState>();
13+
String country = '';
14+
String city = '';
15+
List<String> cities = [];
16+
17+
@override
18+
void initState() {
19+
country = _allCountries.first;
20+
city = _allUsaCities.first;
21+
cities = _allUsaCities;
22+
super.initState();
23+
}
24+
25+
@override
26+
Widget build(BuildContext context) {
27+
return FormBuilder(
28+
key: _formKey,
29+
child: Column(
30+
children: <Widget>[
31+
const SizedBox(height: 20),
32+
FormBuilderDropdown<String>(
33+
name: 'country',
34+
decoration: const InputDecoration(
35+
label: Text('Countries'),
36+
),
37+
initialValue: country,
38+
onChanged: (value) {
39+
setState(() {
40+
country = value ?? '';
41+
city = '';
42+
changeCities();
43+
});
44+
},
45+
items: _allCountries
46+
.map((e) => DropdownMenuItem(
47+
value: e,
48+
child: Text(e),
49+
))
50+
.toList(),
51+
),
52+
const SizedBox(height: 10),
53+
FormBuilderDropdown<String>(
54+
name: 'city',
55+
decoration: const InputDecoration(
56+
label: Text('Cities'),
57+
),
58+
initialValue: city,
59+
items: cities
60+
.map((e) => DropdownMenuItem(
61+
value: e,
62+
child: Text(e),
63+
))
64+
.toList(),
65+
),
66+
const SizedBox(height: 10),
67+
MaterialButton(
68+
color: Theme.of(context).colorScheme.secondary,
69+
child: const Text(
70+
"Submit",
71+
style: TextStyle(color: Colors.white),
72+
),
73+
onPressed: () {
74+
_formKey.currentState!.saveAndValidate();
75+
debugPrint(_formKey.currentState?.instantValue.toString() ?? '');
76+
},
77+
),
78+
],
79+
),
80+
);
81+
}
82+
83+
void changeCities() {
84+
switch (country) {
85+
case 'France':
86+
cities = _allFranceCities;
87+
break;
88+
case 'United States':
89+
cities = _allUsaCities;
90+
break;
91+
default:
92+
cities = [];
93+
}
94+
}
95+
}
96+
97+
const _allCountries = [
98+
'United States',
99+
'France',
100+
];
101+
102+
const _allUsaCities = [
103+
'California',
104+
'Another city',
105+
];
106+
107+
const _allFranceCities = [
108+
'Paris',
109+
'Another city',
110+
];

lib/src/fields/form_builder_dropdown.dart

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -254,47 +254,39 @@ class FormBuilderDropdown<T> extends FormBuilderFieldDecoration<T> {
254254
builder: (FormFieldState<T?> field) {
255255
final state = field as _FormBuilderDropdownState<T>;
256256

257-
void changeValue(T? value) {
258-
state.didChange(value);
259-
}
260-
261-
return InputDecorator(
257+
final hasValue = items.map((e) => e.value).contains(field.value);
258+
return DropdownButtonFormField<T>(
259+
isExpanded: isExpanded,
262260
decoration: state.decoration,
263-
isEmpty: state.value == null,
264-
child: DropdownButtonHideUnderline(
265-
child: DropdownButton<T>(
266-
isExpanded: isExpanded,
267-
items: items,
268-
value: field.value,
269-
style: style,
270-
isDense: isDense,
271-
disabledHint: field.value != null
272-
? (items
273-
.firstWhereOrNull((dropDownItem) =>
274-
dropDownItem.value == field.value)
275-
?.child ??
276-
Text(field.value.toString()))
277-
: disabledHint,
278-
elevation: elevation,
279-
iconSize: iconSize,
280-
icon: icon,
281-
iconDisabledColor: iconDisabledColor,
282-
iconEnabledColor: iconEnabledColor,
283-
onChanged:
284-
state.enabled ? (value) => changeValue(value) : null,
285-
onTap: onTap,
286-
focusNode: state.effectiveFocusNode,
287-
autofocus: autofocus,
288-
dropdownColor: dropdownColor,
289-
focusColor: focusColor,
290-
itemHeight: itemHeight,
291-
selectedItemBuilder: selectedItemBuilder,
292-
menuMaxHeight: menuMaxHeight,
293-
borderRadius: borderRadius,
294-
enableFeedback: enableFeedback,
295-
alignment: alignment,
296-
),
297-
),
261+
items: items,
262+
value: hasValue ? field.value : null,
263+
style: style,
264+
isDense: isDense,
265+
disabledHint: field.value != null
266+
? (items
267+
.firstWhereOrNull((dropDownItem) =>
268+
dropDownItem.value == field.value)
269+
?.child ??
270+
Text(field.value.toString()))
271+
: disabledHint,
272+
elevation: elevation,
273+
iconSize: iconSize,
274+
icon: icon,
275+
iconDisabledColor: iconDisabledColor,
276+
iconEnabledColor: iconEnabledColor,
277+
onChanged:
278+
state.enabled ? (T? value) => state.didChange(value) : null,
279+
onTap: onTap,
280+
focusNode: state.effectiveFocusNode,
281+
autofocus: autofocus,
282+
dropdownColor: dropdownColor,
283+
focusColor: focusColor,
284+
itemHeight: itemHeight,
285+
selectedItemBuilder: selectedItemBuilder,
286+
menuMaxHeight: menuMaxHeight,
287+
borderRadius: borderRadius,
288+
enableFeedback: enableFeedback,
289+
alignment: alignment,
298290
);
299291
},
300292
);
@@ -305,4 +297,12 @@ class FormBuilderDropdown<T> extends FormBuilderFieldDecoration<T> {
305297
}
306298

307299
class _FormBuilderDropdownState<T>
308-
extends FormBuilderFieldDecorationState<FormBuilderDropdown<T>, T> {}
300+
extends FormBuilderFieldDecorationState<FormBuilderDropdown<T>, T> {
301+
@override
302+
void didUpdateWidget(covariant FormBuilderDropdown<T> oldWidget) {
303+
super.didUpdateWidget(oldWidget);
304+
if (widget.items != oldWidget.items) {
305+
setValue(initialValue);
306+
}
307+
}
308+
}

0 commit comments

Comments
 (0)