'Flutter Form Builder - FormBuilderDropdown does not display correct value on screen
I am creating a form with the plugin flutter_form_builder
(https://pub.dev/packages/flutter_form_builder).
When I use FormBuilderDropdown
, you can selected a different value, but it won't show you the selected value on screen. Normally you have a value
property, but this widget does not have that. It only has an initial value
.
Note
When I removed the whole onChanged
method, it does show me the right value on the screen. BUT I need this onChanged method so I cannot remove it...
Code from
final shippingPackagesList = [
{"key": "dhlpwc-parcelshop", "label": "DHL ServicePoint"},
{"key": "dhlpwc-home", "label": "Thuis bezorgen"},
{
"key": "local_pickup:7",
"label": "Afhalen in de winkel in Heerlen, Limburg"
},
];
return Column(
children: [
FormBuilder(
autovalidateMode: AutovalidateMode.always,
key: _formKey,
child: Column(
children: [
const SizedBox(height: 5.0),
FormBuilderDropdown(
items: shippingPackagesList
.map((shippingPackage) =>
DropdownMenuItem(
value: shippingPackage['key'],
child: Text(shippingPackage['label']!),
))
.toList(),
name: 'shipping_key',
onChanged: (value) {
String shippingPackageKey =
value.toString();
// Set selected shipping method in cart view model
cartViewModel
.setSelectedShippingPackageByString(
shippingPackageKey);
cartViewModel.updateTotalCosts();
},
// initialValue: "dhlpwc-parcelshop",
hint: Text("Kies verzendmethode"),
decoration: const InputDecoration(
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.zero)),
contentPadding: EdgeInsets.all(8.0),
)),
const SizedBox(height: 10.0),
],
)),
Text(
'€ ${cartViewModel.selectedShippingPackage!.totalCost.toStringAsFixed(2)}',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
]
)
How can I solve this problem? Or is this a bug?
EDIT
Cart view model functions
class CartViewModel extends ChangeNotifier {
// Properties
ShippingPackage? _selectedShippingPackage;
double? _totalWithShippingPrice;
// Getters
ShippingPackage? get selectedShippingPackage => _selectedShippingPackage;
double? get totalWithShippingPrice => _totalWithShippingPrice;
void setSelectedShippingPackageByString(String shippingPackageKey) {
for (var shippingPackage in cart!.shippingPackages) {
if (shippingPackage.key == shippingPackageKey) {
_selectedShippingPackage = shippingPackage;
}
}
notifyListeners();
}
void updateTotalCosts() {
double total =
cart!.totals.articlesWithTax + selectedShippingPackage!.totalCost;
_totalWithShippingPrice = total;
notifyListeners();
}
}
Main
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartViewModel()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'App',
home: Scaffold(
body: MyMainHome(),
),
),
);
}
Pubspec yaml
add provider: ^6.0.2
in pubspec.yaml
Solution 1:[1]
I experimented with the flutter_form_builder
and the FormBuilderDropdown
specifically. Writing this code based on the example of the package:
class Home72124205 extends StatefulWidget {
const Home72124205({Key? key}) : super(key: key);
@override
State<Home72124205> createState() => _Home72124205State();
}
class _Home72124205State extends State<Home72124205> {
List<String> locationsList = [
'New York',
'Tokyo',
'London',
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FormBuilderDropdown(
name: 'location',
decoration: const InputDecoration(
labelText: 'Location',
),
initialValue: locationsList.first,
allowClear: true,
onChanged: (value){
print(value);
},
items: locationsList
.map((location) => DropdownMenuItem(
value: location,
child: Text(location),
)).toList(),
),
),
);
}
}
I was not able to reproduce your issue. The widget works as intended. The label on the dropdown
changes, the onChange
gets called and the code gets executed.
As we don't have access to your full application, I am unable debug your issue.
Are you able to experiment with this example and test if, within the context of your application, the problem still happens?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | João Soares |