How do I ensure that a user does not select the same security question twice by hiding the initially selected question from appearing in the second dropdown button and vice versa in flutter?. i am making a request to the same api for the questions. Updated the question with some code snippets. Thanks
Container(
height: 60,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: Colors.black,
width: 1),
borderRadius: BorderRadius.circular(5),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: Padding(
padding: const EdgeInsets.only(left:
20.0),
child: Text(
"Security Question Two",
style: TextStyle(
color: Colors.black,
fontSize: 16,
letterSpacing: 0.3,
fontWeight: FontWeight.w300),
),
),
itemHeight: 100,
isExpanded: true,
value: dropDownSecurityQuestionTwo,
icon: Padding(
padding: const EdgeInsets.only(right:
10.0),
child:
Icon(Icons.keyboard_arrow_down_outlined),
),
iconEnabledColor: Colors.black,
iconSize: 30,
style: TextStyle(
color: Colors.black,
),
items: questions.map((value) {
return DropdownMenuItem(
value: value['ID'].toString(),
child: Padding(
padding: const EdgeInsets.only(left:
20.0),
child: Text(
value['question'].toString(),
),
),
);
}).toList(),
onChanged: (newValue) async {
setState(() {
dropDownSecurityQuestionTwo =
newValue.toString();
print(dropDownSecurityQuestionTwo);
checkSelectedQuestion();
});
},
),
),
),
void checkSelectedQuestion(){
List newQuestions = [];
for(int i = 0; i<questions.length; i ){
print(questions[i]['ID']);
questions.removeWhere((value) => value['ID'] ==
int.parse(dropDownSecurityQuestionOne!) );
newQuestions.add(questions);}
setState(() {
questions = newQuestions ;
});}
CodePudding user response:
You can add a where
filter to the mapping of items
to each DropDownButton
, depending on the selected value of the other DropDownButton
. As a result of setState
, the items will be recreated if anything is selected in the other DropDownButton
.
Note: This is easy to implement, but not very efficient. Items will be created and filtered every time. It will work perfectly with few items, but if you would like to do something like this with many items, you might need a more efficient approach. For example keep two items lists, and only add / remove what is affected.
Check this code and adopt it to your case:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyPage(),
);
}
}
class MyPage extends StatefulWidget {
const MyPage({Key? key}) : super(key: key);
@override
State<MyPage> createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
String? _selected1;
String? _selected2;
final List<String> _set = ['Alpha', 'Bravo', 'Charlie'];
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: [
DropdownButton<String>(
value: _selected1,
onChanged: (String? newValue) {
setState(() {
_selected1 = newValue!;
});
},
items: _set
.map((value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
})
.where((e) => _selected2 == null || e.value != _selected2)
.toList()),
DropdownButton<String>(
value: _selected2,
onChanged: (String? newValue) {
setState(() {
_selected2 = newValue!;
});
},
items: _set
.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
})
.where((e) => _selected1 == null || e.value != _selected1)
.toList()),
]),
),
),
);
}
}