Flutter: How to make my fields required and save my dropdown and text data after the submit button is pressed?

Issue

Here is my code. I’m unable to save the responses and even the dropdown and the text fields are not showing the required text and the * sign with them. I can’t get how can I save the responses submitted by the user and where to do it and what should I write on the on Pressed function in the submit button to save the responses of all the fields above it.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

void main() {
runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
TextEditingController problemBox = TextEditingController();

List _listItem = ["Category 1", "Category 2", "Category 3", "Category 4"];
List _listItem1 = [
"Sub Category 1",
"Sub Category 2",
"Sub Category 3",
"Sub Category 4"
];
List _listItem2 = ["CRIS", "ADMINISTRATION", "ZONE", "DEPARTMENT"];

String dropdownValue;
String holder = '';

void getDropDownItem() {
setState(() {
  holder = dropdownValue;
});
}

String dropdownValue1;
String holder1 = '';

void getDropDownItem1() {
setState(() {
  holder1 = dropdownValue1;
});
}

String dropdownValue2;
String holder2 = '';

void getDropDownItem2() {
setState(() {
  holder2 = dropdownValue2;
});
}

bool autoValidate = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

@override
Widget build(BuildContext context) {
return Scaffold(
    resizeToAvoidBottomInset: false,
    appBar: AppBar(
      title: Text("Feedback"),
      centerTitle: true,
      leading: IconButton(
        onPressed: () {},
        icon: Icon(Icons.home),
      ),
    ),
    body: Container(
        child: Center(
      child: SingleChildScrollView(
        child: Form(
          autovalidateMode: AutovalidateMode.onUserInteraction,
          key: _formKey,
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Text("CATEGORY"),
                    DropdownButton<String>(
                      hint: Text("Select"),
                      value: dropdownValue,
                      items: _listItem
                          .map<DropdownMenuItem<String>>((valueItem) {
                        return DropdownMenuItem<String>(
                          value: valueItem,
                          child: Text(valueItem),
                        );
                      }).toList(),
                      onChanged: (value) {
                        setState(() {
                          dropdownValue = value;
                        });
                      },
                    )
                  ],
                ),
                SizedBox(
                  height: 10,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Text("SUBCATEGORY"),
                    DropdownButton<String>(
                      hint: Text("Select"),
                      value: dropdownValue1,
                      items: _listItem1
                          .map<DropdownMenuItem<String>>((valueItem1) {
                        return DropdownMenuItem<String>(
                          value: valueItem1,
                          child: Text(valueItem1),
                        );
                      }).toList(),
                      onChanged: (value) {
                        setState(() {
                          dropdownValue1 = value;
                        });
                      },
                    )
                  ],
                ),
                SizedBox(height: 10),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Text("MARKED TO"),
                    DropdownButton<String>(
                      hint: Text("Select"),
                      value: dropdownValue2,
                      items: _listItem2
                          .map<DropdownMenuItem<String>>((valueItem2) {
                        return DropdownMenuItem<String>(
                          value: valueItem2,
                          child: Text(valueItem2),
                        );
                      }).toList(),
                      onChanged: (value) {
                        setState(() {
                          dropdownValue2 = value;
                        });
                      },
                    )
                  ],
                ),
                SizedBox(height: 10),
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Padding(
                      padding: EdgeInsets.fromLTRB(70, 00, 70, 00),
                      child: TextFormField(
                        validator: (String value) {
                          if (value.isEmpty) {
                            return "Name is required";
                          }
                          return null;
                        },
                        controller: problemBox,
                        decoration: InputDecoration(
                          hintText: "Describe your problem here.",
                        ),
                        maxLength: 1000,
                        maxLines: 5,
                      ),
                    )
                  ],
                ),
                SizedBox(height: 10),
                ButtonTheme(
                  child: ElevatedButton(
                    child: Text("Submit"),
                    onPressed: () {
                      _formKey.currentState.save();

                    },
                    style: ElevatedButton.styleFrom(
                      padding: EdgeInsets.symmetric(
                          horizontal: 25, vertical: 15),
                    ),
                  ),
                ),
              ]),
        ),
      ),
    )));
 }

Solution

To show the error of the textField check if the Form is validate :

 ButtonTheme(
                          child: ElevatedButton(
                            child: Text("Submit"),
                            onPressed: () {
                             if(
                             _formKey.currentState.validate() // add this
                             ) {
                               print(" form is valideate"); // here do what you want when the form is validate :) 
                             }

                            },
                            style: ElevatedButton.styleFrom(
                              padding: EdgeInsets.symmetric(
                                  horizontal: 25, vertical: 15),
                            ),
                          ),
                        )

To validate dropDown , change DropdownButton to DropdownButtonFormField has a property validator –

  Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Flexible(child: Text("MARKED TO")),
                        Flexible(
                          child: DropdownButtonFormField<String>( // change to DropdownButtonFormField
                            hint: Text("Select"),
                            value: dropdownValue2,
     validator: (value) => value == null ? 'your message' : null,// add validator property
                            items: _listItem2
                                .map<DropdownMenuItem<String>>((valueItem2) {
                              return DropdownMenuItem<String>(
                                value: valueItem2,
                                child: Text(valueItem2),
                              );
                            }).toList(),
                            onChanged: (value) {
                              setState(() {
                                dropdownValue2 = value;
                              });
                            },
                   
                          ),
                        )
                      ],
                    ),

and for * you can juste add it to required fields

Ex :

RichText(
                          textAlign: TextAlign.center,
                          text: TextSpan(
                            text: 'MARKED TO',
        
                            children: <TextSpan>[
                              TextSpan(
                                text: '*',
                                style: TextStyle(color: Colors.red),
                              ),
                            ],
                          ),
                    )

Answered By – Fatima ayaa

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *