I am using the following code to create a simple multi-steps question-answer form, but it seems forms can not hold their values and when I go to the second form and come back, the textFormField
values are gone.
"Create.dart":
class Create with ChangeNotifier {
String? title;
String? description;
int activeIndex = 0;
int totalIndex = 6;
changeStep(int index) {
activeIndex = index;
notifyListeners();
}
}
"handler.dart":
class FormCreateHandler extends StatefulWidget {
const FormCreateHandler({super.key});
static const routeName = '/-form-handler';
@override
State<FormCreateHandler> createState() =>
_FormCreateHandlerState();
}
class _FormCreateHandlerState extends State<FormCreateHandler> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Create>(
create: (context) => Create(),
child: Consumer<Create>(
builder: (context, modal, child) {
switch (modal.activeIndex) {
case 0:
return const FormQuestion1();
case 1:
return const FormQuestion2();
default:
return const FormQuestion1();
}
},
),
);
}
}
"form-question1.dart":
class FormQuestion1 extends StatefulWidget {
const FormQuestion1({super.key});
static const routeName = '/form-question1';
@override
State<FormQuestion1> createState() => _FormQuestion1State();
}
class _FormQuestion1State extends State<FormQuestion1> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Consumer<Create>(builder: (context, modal, child) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'title',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty)
return 'Please enter the title of question';
},
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'description',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length < 30) {
return 'Description must be longer';
}
},
),
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(2);
}
},
child: Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: null,
child: Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(4);
}
},
child: Text('Next'),
),
),
],
),
),
],
),
),
);
});
}
}
"form-question2.dart"
class FormQuestion2 extends StatefulWidget {
const FormQuestion2({super.key});
static const routeName = '/form-question2';
@override
State<FormQuestion2> createState() => _FormQuestion2State();
}
class _FormQuestion2State extends State<FormQuestion2> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Consumer<Create>(builder: (context, modal, child) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'title',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty)
return 'Please enter the title of question';
},
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'description',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length < 30) {
return 'Description must be longer';
}
},
),
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(2);
}
},
child: Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: null,
child: Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(4);
}
},
child: Text('Next'),
),
),
],
),
),
],
),
),
);
});
}
}
How can I modify this code to be able to hold the state of the forms until the user either presses the Submit button or closes the form?
2
Answers
Based on the other answer by @Aks, I came from a new idea to modify my question forms like below:
"form-question1.dart":
The modifications are adding following
initialValue
andonSaved()
properties to eachtextFormField
:But as I am not sure if this is the best way of doing that, this question remains open maybe someone would help me to improve the answer furthermore!
Here’s an example with TextEditingController
home_page.dart //with TextEditingController
When you navigate to next page and come back then the _text state will remain same and when you want to clear it then updateTextValue("")
home_page.dart //with onChanged(value)