I'm using flutter_form_builder to create my forms. The user will create his own poll using the form, and he/she will add choices to his/her question as much as needed. I solved the dynamic addition of choices part, but the problem now is; when I create a question with one choice and hit the submit button, the choice, the question and the date gets printed in the console, but if I hit the fab button to create another choice, only the newly created field will print it's content along with the date and the question, and the older field gets disregarded.
How can I get the results of every field gets created dynamically..
Thanks in advance..
Here's my code:-
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
class AddPoll extends StatefulWidget {
@override
_AddPollState createState() => _AddPollState();
}
class _AddPollState extends State<AddPoll> {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<Widget> choiceFieldList;
void initState() {
super.initState();
choiceFieldList = <Widget>[];
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text("Create a poll")),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
choiceFieldList.add(ChoiceField());
});
}
),
body: Padding(
padding: EdgeInsets.all(10.0),
child: SingleChildScrollView(
child: Column(
children: [
FormBuilder(
key: _fbKey,
initialValue: {
'date': DateTime.now()
},
autovalidateMode: AutovalidateMode.always,
child: Column(
children: <Widget>[
FormBuilderTextField(
attribute: 'question',
validators: [FormBuilderValidators.required()],
maxLines: null,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText: "Your Question",
border: OutlineInputBorder()
)
),
Container(
padding: EdgeInsets.fromLTRB(0, 30, 0, 20),
alignment: Alignment.centerLeft,
child: Text(
"Choices:-",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
)
)
),
ListView.builder(
shrinkWrap: true,
itemCount: choiceFieldList.length,
itemBuilder: (context, index) => choiceFieldList[index],
),
Visibility(
visible: false,
child: FormBuilderDateTimePicker(
attribute: "date",
inputType: InputType.both,
validators: [FormBuilderValidators.required()],
format: DateFormat("dd-MM-yyyy 'at' h:mma"),
decoration: InputDecoration(labelText: "Date of Poll")
)
)
]
)
),
SizedBox(height: 30.0),
ButtonBar(
alignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: Text("Reset"),
onPressed: () {
_fbKey.currentState.reset();
}
),
RaisedButton(
child: Text("Submit"),
onPressed: () async {
_fbKey.currentState.save();
print(_fbKey.currentState.value);
if (_fbKey.currentState.validate()) {
// Loading().show(context);
// var date = _fbKey.currentState.value['date'];
// var resp = await registerUser(date);
}
}
)
]
)
]
)
)
)
)
);
}
}
class ChoiceField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: FormBuilderTextField(
attribute: 'choice',
validators: [FormBuilderValidators.required()],
decoration: InputDecoration(
labelText: "Enter Choice",
border: OutlineInputBorder()
)
)
);
}
}
You can copy paste run full code below
You need to provide different
attribute
nameyou can use
attributeName: "choice ${choiceFieldList.length}"
code snippet
output
working demo
full code