I get my error message "All fields are required". I'm not sure how Map<String,TextEditingController>
works. I've tried searching but can't find much on Map
being used with TextEditingController
. Just want to know if I'm on the right track or if I should be doing something different. I'm trying to post a note that has a growing TextField
(every time the user taps submit a new TextField appears). But but using the code for that I haven't been able to print or post more than 1 one line form the TextFields. Can I use notesControllers
to print/post the users input from all TextFields?
And sorry if you've seen similar questions from me, this is going on day 10 of trying to figure this problem out. Any help is much appreciated.
This is some of what I've tried:
class AddNoteScreenEdit extends StatefulWidget {
User user;
AddNoteScreenEdit({
required this.user,
});
@override
State<AddNoteScreenEdit> createState() => _AddNoteScreenEditState();
}
class _AddNoteScreenEditState extends State<AddNoteScreenEdit> {
// TextEditingController notesController = TextEditingController();
Map<String, TextEditingController> notesControllers = {};
// List<TextEditingController> noteControllers = [];
FirebaseFirestore firestore = FirebaseFirestore.instance;
bool loading = false;
String? str;
List<TextField> textFields = [];
@override
void initState() {
super.initState();
textFields.add(_buildTextField(notesControllers));
//notesControllers;
// notesControllers[str]?.text;
// notesControllers[str]?.text = 'test';
// notesControllers[str]?.text = [] as String;
// TextEditingController notesControllers = TextEditingController(text: str);
}
@override
Widget build(BuildContext context) {
// var str = [];
//var stringListReturnedFromApiCall = [] as String;
//var stringListReturnedFromApiCall = [];
// var noteControllers = TextEditingController(text: str);
//var noteControllers = TextEditingController(text: str);
// Map<String, TextEditingController> notesControllers = {};
// //var textFields = <TextField>[];
// // textFields.add(_buildTextField());
// stringListReturnedFromApiCall.forEach((str) {
// var notesController = new TextEditingController(text: str);
// notesControllers.putIfAbsent(str, () => notesController);
// return textFields.add(TextField(controller: notesControllers));
// // return textFields.add(_buildTextField());
// });
// var stringListReturnedFromApiCall = [];
// Map<String, TextEditingController> notesEditingControllers = {};
// var textFields = <TextField>[];
// textFields.add(_buildTextField());
// stringListReturnedFromApiCall.forEach((str) {
// var notesEditingController = new TextEditingController(text: str);
// notesEditingControllers.putIfAbsent(str, () => notesEditingController);
// return textFields.add(TextField(controller: notesEditingController));
// });
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xFF162242),
elevation: 0,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
child:
// TextField(controller: noteControllers)
ListView(
children: textFields,
shrinkWrap: true,
),
),
loading
? Center(
child: CircularProgressIndicator(),
)
: Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
onPressed: () async {
// () => stringListReturnedFromApiCall.forEach((str) async {
// print(notesControllers[str]?.text);
if (notesControllers[str] != null) {
return loading
? Center(child: CircularProgressIndicator())
: print(notesControllers[str]?.text);
} else if (notesControllers[str]?.text.isEmpty ??
true) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("All fields are required")));
} else {
setState(() {
loading = true;
});
await FirestoreServiceEdit().insertNote(
notesControllers[str]!.text, widget.user.uid);
CollectionReference notes =
firestore.collection('notes');
QuerySnapshot allResults = await notes.get();
allResults.docs.forEach((DocumentSnapshot result) {
print(result.data());
});
setState(() {
loading = false;
});
Navigator.pop(context);
}
},
//),
// ),
child: Text(
"Add Note",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF162242)),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
),
]),
),
),
),
);
}
TextField _buildTextField(
Map<String, TextEditingController> notesControllers) {
return TextField(
//controller: notesControllers,
//controller: notesControllers[str],
// controller: TextEditingController(),
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
decoration: InputDecoration(
prefix: Icon(
Icons.circle,
size: 8,
color: Colors.black,
),
),
autofocus: true,
onSubmitted: (String? str) {
setState(() {
textFields.add(_buildTextField(notesControllers));
// notesControllers[str]?.text = 'test';
// TextEditingController notesControllers = TextEditingController(text: str);
// notesControllers;
// notesControllers[str]?.text;
// notesControllers[str]?.text = str ?? '';
// notesControllers[str]?.text = [] as String;
// var noteControllers = TextEditingController(text: str);
// var stringListReturnedFromApiCall = [];
// var stringListReturnedFromApiCall = ['test', 'testing', 'test'];
// Map<String, TextEditingController> notesControllers = {};
// // var textFields = <TextField>[];
// // textFields.add(_buildTextField());
// stringListReturnedFromApiCall.forEach((str) {
// var notesController = new TextEditingController(text: str);
// notesControllers.putIfAbsent(str, () => notesController);
// return textFields.add(TextField(controller: notesController));
// //return textFields.add(_buildTextField());
// });
});
});
}
}
class NoteModelEdit {
String id;
String? notes;
String userId;
NoteModelEdit({
required this.id,
required this.notes,
required this.userId
});
factory NoteModelEdit.fromJson(DocumentSnapshot snapshot){
return NoteModelEdit(
id: snapshot.id,
notes: snapshot['notes'],
userId: snapshot['userId']
);
}
}
class FirestoreServiceEdit{
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future insertNote(String? notes, String? userId)async{
try{
await firestore.collection('notes').add({
"notes":notes,
"userId":userId
});
} catch (e) {}
}
}
Home screen:
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection("notes").where('userId', isEqualTo: user.uid).snapshots(),
builder: (context, AsyncSnapshot snapshot){
if (snapshot.hasData){
if(snapshot.data.docs.length > 0){
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context,index) {
NoteModelEdit note = NoteModelEdit.fromJson(snapshot.data.docs[index]);
return Card(
margin: EdgeInsets.only(top: 16, left: 10, right: 10, bottom: 16),
child: Column(
children: [
ListTile(title: Center(child:
Text(note.notes!),),
),
Thank you for your time!
CodePudding user response:
You can keep lists of TextField
s and TextEditingController
s and use a ListView.builder
to display them. On each submit, just add a new field and controller to your lists. When you want to save, loop through your controller list and grab each text.
Initialize your lists in a StatefulWidget
:
final List<TextField> _textFields = [];
final List<TextEditingController> _controllers = [];
@override
void initState() {
super.initState();
_addTextField();
}
void _addTextField() {
final controller = TextEditingController();
_textFields.add(
TextField(
controller: controller,
onSubmitted: (_) => setState(() => _addTextField()),
),
);
_controllers.add(controller);
}
Inside your parent widget:
ListView.builder(
itemCount: _textFields.length,
itemBuilder: (_, index) {
return _textFields[index];
}
),
Here is a quick example that should get you going.