DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for How to build a Flutter Form for managing questions and their answers
Obumuneme Nwabude
Obumuneme Nwabude

Posted on • Updated on

How to build a Flutter Form for managing questions and their answers

What we will be building ...

A one-screen flutter app containing a form. The form can be used to create/update a question and its options (and the correct option too). This interface is for setting questions that could be used elsewhere like an online quiz. The whole question data can then be saved to a database like Firebase Firestore. The screen looks like this:

UI of Question Form built with Flutter

Prerequisites

  • Have basic understanding of flutter and probably programming as a whole.
  • Have installed flutter and its working.

Steps

1. Setup

Initialize the flutter project by running the following command in your terminal

flutter create questions
Enter fullscreen mode Exit fullscreen mode

2. Coding

a. Open the project in your favorite editor.
b. Delete the contents of lib/main.dart file, paste the following code, and save the file.

3. Run

Run the code with the following command

flutter run
Enter fullscreen mode Exit fullscreen mode

The app should run in your attached device and it should show something similar to the above UI.

More on the Question Form

Iteration/Looping

It is good practice to make code short or DRY (Don't Repeat Yourself). The code for the "correct option radio buttons" and the "TextFormFields for the option values" are the same. For these two sections of Widgets, we are looping over the list of options

const options = ['A', 'B', 'C', 'D'];
Enter fullscreen mode Exit fullscreen mode

to return each necessary Widget.

The Radio, Text (for each option), and spacer (const SizedBox(width: 16)) are been repeated together, reason why we had to call the expand method on Iterable to expand the list of lists been returned. Same is applicable for the TextFormField for each option's value and its own spacer (const SizedBox(height: 32)) as they are been returned together too in the map function.

  \\ ... ,
  const Text('Correct Option'),
  Row(
      children: options
          .map((option) => [
                Radio<String>(
                  value: option,
                  groupValue: _question['correct'] as String,
                  onChanged: (v) => setState(() => _question['correct'] = v!),
                ),
                Text(option),
                const SizedBox(width: 16)
              ])
          .expand((w) => w)
          .toList()),
  const SizedBox(height: 32),
  ...options
      .asMap()
      .entries
      .map((entry) => [
            TextFormField(
              controller: _optionCtrls[entry.key],
              decoration: InputDecoration(labelText: 'Option ${entry.value}*'),
              validator: (v) =>
                  v!.isEmpty ? 'Please fill in Option ${entry.value}' : null,
            ),
            const SizedBox(height: 32),
          ])
      .expand((w) => w),
  \\ ...
Enter fullscreen mode Exit fullscreen mode

Validation

Form validation in flutter is achieved by providing a validator function as an argument to the validator named parameter of the TextFormField. The validator function should return null if the input is valid, else it should return an error message if the input is invalid (or empty in our case).

validator: (v) => v!.isEmpty ? 'Please fill in the Question' : null
Enter fullscreen mode Exit fullscreen mode

Flutter Question Form with error messages under TextFormFields

Feedback to user with SnackBar

The submit button of forms are usually disabled if the form is invalid (has errors) in some apps. However, the user might not know why the button is disabled and that will be poor user experience.

Good user experience entails giving feedback to user when they take actions on your app. That's why those error messages on the Form show up when the user leaves the fields empty. Instead of disabling the submit button, we instead check for the form's validity when the button is pressed.

If the form is valid, we collect the question data and show the snackbar with success message. If on the other hand the form is invalid, we show the snackbar with the error message.

ElevatedButton(
  onPressed: () {
    if (_formKey.currentState!.validate()) {
      _question['value'] = _questionCtrl.text;
      _question['options'] = _optionCtrls.asMap().entries.map(
        (entry) {
          return {
            'index': options[entry.key],
            'value': entry.value.text,
          };
        },
      );
      if (kDebugMode) {
        print(_question);
      }
      showSnackbar(
        success: true,
        text: 'Question updated successfully.',
      );
    } else {
      showSnackbar(
        success: false,
        text: 'Please fill all the required fields.',
      );
    }
  },
  child: const Text('Update'),
)
Enter fullscreen mode Exit fullscreen mode

Error Snackbar in Flutter Question Form

Customizing the SnackBar

Displaying a SnackBar is easy with Flutter. By default, the snackbar pops in the bottom with full screen with. But we can customize the snackbar to appear at the top of the screen, in order to quickly catch the user's attention. We can also make the snackbar float by giving it some left and right margins.

Notice how we used a function: showSnackbar, that takes an IconData (to be displayed in the snackbar), text to be displayed, and a success bool, that is used to determine the color of the displayed icon.

void showSnackbar({required bool success, required String text}) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      margin: EdgeInsets.only(
        bottom: MediaQuery.of(context).size.height - 96,
        right: 16,
        left: 16,
      ),
      behavior: SnackBarBehavior.floating,
      content: Row(children: [
        Icon(
          success ? Icons.gpp_good : Icons.error,
          color: success ? Colors.greenAccent : Colors.redAccent,
        ),
        const SizedBox(width: 8),
        Text(text),
      ]),
    ),
  );
}
Enter fullscreen mode Exit fullscreen mode

Success Snackbar in Flutter Question Form

Final Thoughts

Flutter is a good framework for mobile development. Developer experience with flutter is smooth and the lines of code are shorter compared to other frameworks.

Forms are an important part of many apps as they help in collecting data. In our flutter app, we used a form to collect data about a question been set/created. This Flutter Question Form may not do much because the data is not been submitted anywhere. But then, we have successfully built a UI that can serve for setting questions that could be saved to some database.

Up Next

We will use this form to build an app that can edit many questions to be set for an online quiz.

Top comments (0)

Layoffs: It’s Okay to Not Be Okay