I have 2 DropdownButtonFormField
s where I have a selection of cars. I need to change the second selection of buttons according to the car model user has chosen from the first selection in the DropdownButtonFormField (i.e. If a user chooses a Mercedes in the first one, in the DropdownButtonFormField below, I want to display only models of Mercedes and not, let's say, Audi).
How can I achieve this? Here is the code:
String _make, _model;
/// List of cars and models
List<String> carList = [
'Audi',
'BMW',
'Mercedes',
];
List<String> modelAudi = ['A6', 'A8', 'Q7',];
List<String> modelMercedes = ['E-Class', 'S-Class','Maybach'];
List<String> modelBMW = ['3-Series', 'X5', 'X7'];
/*two DropdownButtonFormFields, but the second one needs to match
it's car manufacturer selection from the carList selection
(i.e. if you select Audi, it must only show the modelAudi list (A6,
A8, Q7) in the second DropdownButtonFormField)
*/
DropdownButtonFormField<String>(
value: _make,
items: carList
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
onChanged: (value) {
setState(() {
_make = value;
print(value);
});
},
),
DropdownButtonFormField<String>(
value: _model,
/* here is where I need to implement logic
that maps out the model names that matches the car maker
*/
items: modelAudi
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
onChanged: (value) {
setState(() {
_model = value;
print(value);
});
},
),
The DropDown for the first button:
And naturally because I have no logic behind it, I get this as the model selection whatever I chose from the car list, but I want it to map out only models from the car list you chose.
CodePudding user response:
This is a great use case for a switch statement. Define your cases for each car maker according to this example:
String _maker;
List chosenMakerModel;
switch (_maker) {
case 'Audi':
chosenMakerModel = modelAudi;
break;
case 'BMW':
// implement logic:
break;
case 'OTHER MANUFACTURER':
// implement logic;
break;
}
Using the example code above use chosenMakerModel
instead of modelAudi
CodePudding user response:
You can create a model selection method to handle this situation, like
List<String> _selectModel(String? modelName) {
return modelName == carList[0]
? modelAudi
: modelName == carList[1]
? modelMercedes
: modelBMW; // initally it will have modelBMW
}
This will decide the second dropdown item. If you click to select the second drop down item 1st, it will through errors. To handle this situation, you need to update the second dropdown value as well. You can set the second dropdown value=null
. Therefor we need to use nullable String for selection value.
class MyProfileState extends State<StatefulWidget> {
String? _make, _model;
/// List of cars and models
List<String> carList = ['Audi', 'BMW', 'Mercedes'];
List<String> modelAudi = ['A6', 'A8', 'Q7'];
List<String> modelMercedes = ['E-Class', 'S-Class', 'Maybach'];
List<String> modelBMW = ['3-Series', 'X5', 'X7'];
List<String> _selectModel(String? modelName) {
return modelName == carList[0]
? modelAudi
: modelName == carList[1]
? modelMercedes
: modelBMW;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
DropdownButtonFormField<String>(
value: _make,
items: carList
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
onChanged: (value) {
setState(() {
_make = value;
_model = null;
print(value);
});
},
),
DropdownButtonFormField<String>(
value: _model,
items: _selectModel(_make)
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
onChanged: (value) {
setState(() {
_model = value;
print(value);
});
},
),
],
));
}
}