skip to Main Content

What I am trying to do is showing a Dialog that consists of a Form within it to the user, then user fills out the 2 TextFormFields and clicks on the Next ElevatedButton. Then another similar Dialog/form will be appear and user can do the same thing until he wants to finish and press the Submit ElevatedButton (i.e. One user may want to add 3 question/answer and another user 10). Moreover user can click on the Back ElevatedButton and review the previous Dialog/Forms.

T have the following code but it doesn’t work because it can not keep the previous form states and also can’t submit the form:

class _FormQuestionsState extends State<FormQuestions> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: SingleChildScrollView(
        child: Column(
          children: [
            TextFormField(
              decoration: const InputDecoration(
                labelText: 'Queation',
                border: OutlineInputBorder(),
              ),
              validator: (value) {
                if (value!.isEmpty) return 'Please enter the title of the question';
              },
            ),
            TextFormField(
              minLines: 3,
              maxLines: 5,
              decoration: const InputDecoration(
                labelText: 'Answer',
                border: OutlineInputBorder(),
              ),
              validator: (value) {
                if (value!.isEmpty || value.length < 30) {
                  return 'Answer must be longer';
                }
              },

            ),
            Padding(
              padding: EdgeInsets.all(10),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Expanded(
                    flex: 1,
                    child: ElevatedButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                        showDialog(
                            context: context,
                            builder: (context) =>
                                const Dialog(child: FormQuestions()));
                      },
                      child: Text('Back'),
                    ),
                  ),
                  Expanded(
                    flex: 2,
                    child: ElevatedButton(
                      onPressed: null, // This function should save all the information has been already put on all the forms!
                      child: Text('Submit'),
                    ),
                  ),
                  Expanded(
                    flex: 1,
                    child: ElevatedButton(
                      onPressed: () {
                        Navigator.of(context).pop();

                        showDialog(
                            context: context,
                            builder: (context) =>
                                const Dialog(child: FormQuestions()));
                      },
                      child: Text('Next'),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I don’t know how to modify it to reach what I want.

2

Answers


  1. You can loop through the dialogs in following way and save the result.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: 'Demo',
          debugShowCheckedModeBanner: false,
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Center(
            child: TextButton(
              child: const Text('Show Form'),
              onPressed: () => _showForm(context),
            ),
          ),
        );
      }
    
      void _showForm(BuildContext context) async {
        final questionAnswers = <QuestionAnswer>[];
    
        var showNextQuestion = true;
    
        while (showNextQuestion) {
          final formKey = GlobalKey<FormState>();
    
          final returnValue = await showDialog<bool?>(
              context: context,
              useRootNavigator: false,
              builder: (context) {
                String? question, answer;
                return SimpleDialog(
                  children: [
                    Form(
                      key: formKey,
                      child: Column(
                        children: [
                          TextFormField(
                            decoration: const InputDecoration(
                              labelText: 'Question',
                              border: OutlineInputBorder(),
                            ),
                            validator: (value) {
                              if (value!.isEmpty) {
                                return 'Please enter the title of the question';
                              }
                              return null;
                            },
                            onSaved: (value) => question = value,
                          ),
                          TextFormField(
                            minLines: 3,
                            maxLines: 5,
                            decoration: const InputDecoration(
                              labelText: 'Answer',
                              border: OutlineInputBorder(),
                            ),
                            validator: (value) {
                              if (value!.isEmpty || value.length > 30) {
                                return 'Answer must be longer';
                              }
                              return null;
                            },
                            onSaved: (value) => answer = value,
                          ),
                          Padding(
                            padding: const EdgeInsets.all(10),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Expanded(
                                  flex: 1,
                                  child: ElevatedButton(
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                    },
                                    child: const Text('Back'),
                                  ),
                                ),
                                Expanded(
                                  flex: 2,
                                  child: ElevatedButton(
                                    onPressed: () {
                                      if (formKey.currentState!.validate()) {
                                        formKey.currentState?.save();
                                        questionAnswers.add(
                                            QuestionAnswer(question!, answer!));
                                        Navigator.of(context).pop(false);
                                      }
                                    }, // This function should save all the information has been already put on all the forms!
                                    child: const Text('Submit'),
                                  ),
                                ),
                                Expanded(
                                  flex: 1,
                                  child: ElevatedButton(
                                    onPressed: () {
                                      if (formKey.currentState!.validate()) {
                                        formKey.currentState?.save();
                                        questionAnswers.add(
                                            QuestionAnswer(question!, answer!));
    
                                        Navigator.of(context).pop();
                                      }
                                    },
                                    child: const Text('Next'),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                );
              });
    
          showNextQuestion = returnValue ?? showNextQuestion;
        }
    
        if (context.mounted) {
          Navigator.of(context).push(MaterialPageRoute(builder: (context) {
            return Scaffold(
              appBar: AppBar(),
              body: ListView.builder(
                itemBuilder: (context, index) {
                  final item = questionAnswers[index];
                  return ListTile(
                    title: Text(item.question),
                    subtitle: Text(item.answer),
                  );
                },
                itemCount: questionAnswers.length,
              ),
            );
          }));
        }
      }
    }
    
    @immutable
    class QuestionAnswer {
      final String question;
      final String answer;
    
      const QuestionAnswer(this.question, this.answer);
    }
    
    
    Login or Signup to reply.
  2. Use TextEditingController(),
    use some unique string or index for question/answer as key

    Map<String, TextEditingController> inputcontroller = {};
    
    inputcontroller["question1"] = TextEditingController();
    
    TextFormField(
      controller: inputcontroller["question1"],
      decoration: const InputDecoration(
      labelText: 'Question',
        border: OutlineInputBorder(),
      ),
      validator: (value) {
        if (value!.isEmpty) return 'Please enter the title of the question';
        },
      ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search