i have a firestore collection (conttyp) with documents (client, contractor, supplier, employee) and every document have only one (title) field like (عميل, مقاول, تاجر, موظف)
i’m trying to store the value as doc id to a list and save to another table (contact), but need to show the selected item (title) on the button instead of the document id (the value)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class TestScreen extends StatefulWidget {
const TestScreen({super.key});
@override
State<TestScreen> createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> {
final _fireStore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
late User loggedInUser;
List<String> selectedTypeID = [];
List<String> selectedTypeTitle = [];
final TextEditingController textEditingController = TextEditingController();
@override
void dispose() {
textEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder(
stream: _fireStore.collection('conttyp').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: LinearProgressIndicator(
backgroundColor: Colors.amber,
),
);
} else {
return DropdownButtonFormField2<String>(
isExpanded: true,
hint: const Text(
'اختر من القائمة',
style: TextStyle(fontFamily: 'Zahey'),
),
items: snapshot.data!.docs.map((DocumentSnapshot item) {
return DropdownMenuItem<String>(
value: item.id,
//disable default onTap to avoid closing menu when selecting an item
enabled: false,
child: StatefulBuilder(
builder: (context, menuSetState) {
final isSelected = selectedTypeID.contains(item
.id) /* && selectedTypeTitle.contains(item.get('title')) */;
return InkWell(
onTap: () {
isSelected
? {
selectedTypeID.remove(item.id),
selectedTypeTitle
.remove(item.get('title'))
}
: {
selectedTypeID.add(item
.id),
selectedTypeTitle.add(item.get('title'))
};
//This rebuilds the StatefulWidget to update the button's text
setState(() {});
//This rebuilds the dropdownMenu Widget to update the check mark
menuSetState(() {});
},
child: Container(
height: double.infinity,
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(
Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item.get('title'),
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
value: selectedTypeTitle.isEmpty ? null : selectedTypeTitle.last,
onChanged: (value) {},
selectedItemBuilder: (context) {
return snapshot.data!.docs.map(
(item) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedTypeID.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
buttonStyleData: const ButtonStyleData(
height: 40,
width: 200,
),
dropdownStyleData: const DropdownStyleData(
maxHeight: 200,
),
menuItemStyleData: const MenuItemStyleData(
height: 40,
),
dropdownSearchData: DropdownSearchData(
searchController: textEditingController,
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.only(
top: 8,
bottom: 4,
right: 8,
left: 8,
),
child: TextFormField(
expands: true,
maxLines: null,
controller: textEditingController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'بحث...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return (item.value.toString().contains(searchValue));
},
),
//This to clear the search value when you close the menu
onMenuStateChange: (isOpen) {
if (!isOpen) {
textEditingController.clear();
}
},
);
}
}),
),
);
}
}
but getting an error of
items.where((DropdownMenuItem<T> item) { return item.value == value; }).length == 1': There should be exactly one item with [DropdownButton]'s value: عميل. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value)
how to store the title field of the selected document id in another list?
2
Answers
You are getting this error because you’re setting the value of DropdownButtonFormField2 to selectedTypeTitle.last, the last item added to the selectedTypeTitle list. so you can solve them like this,
You should use
id
for yourvalue
instead oftitle
: