Flutter dropdown, select is disabled on validation error

1,289

Looking at your code, I strongly recommend you create 3 different Forms and validate them separately, so you don't have any problem regarding form state. To achieve this, you can just wrap the fields into their respective Form and be sure not to mix the forms nor have them one inside the other.

Below, an example based on your code and on what I have said:

class SignUp extends StatefulWidget {
  @override
  _SignUpState createState() => _SignUpState();
}

class _SignUpState extends State<SignUp> {
  final _page1 = GlobalKey<FormState>();
  final _page2 = GlobalKey<FormState>();
  final _page3 = GlobalKey<FormState>();

  final _key = GlobalKey<ScaffoldState>();
  
  int currentPageValue;

  List<String> _gender = ['Male', 'Female'];
  String _selectedGender;

  void changePage(GlobalKey<FormState> page) {
    if (currentPageValue < 3) {
      if (page.currentState.validate()) {
        setState(() {
          currentPageValue += 1;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      body: ListView(
        children: <Widget>[
          Form(
            key: _page1,
            child: Column(
              children: [
                DropdownButtonFormField(
                  isExpanded: true,
                  hint: Text('Gender'),
                  value: _selectedGender,
                  onChanged: (newValue) {
                    setState(() {
                      _selectedGender = newValue;
                    });
                  },
                  items: _gender.map((gender) {
                    return DropdownMenuItem(
                      child: new Text(gender),
                      value: gender,
                    );
                  }).toList(),
                  validator: (value) {
                    if (value == null) return "Please select your gender";
                    return null;
                  },
                ),
                RaisedButton(
                  child: Text('Next'),
                  onPressed: () => changePage(_page1),
                ),
              ],
            ),
          ),
          Form(
            key: _page2,
            child: Column(
              children: [
                // SomeField(
                //
                // ),
                // SomeOtherField(
                //
                // ),
                RaisedButton(
                  child: Text('Next'),
                  onPressed: () => changePage(_page2),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Share:
1,289
Michael
Author by

Michael

Updated on December 23, 2022

Comments

  • Michael
    Michael over 1 year

    Validation is working well but incase of validation error, option to select on option is disabled.

                                          DropdownButtonFormField(
                                            isExpanded: true,
                                            hint: Text('Gender'),
                                            value: _selectedGender,
                                            onChanged: (newValue) {
                                              setState(() {
                                                _selectedGender = newValue;
                                              });
                                            },
                                            items: _gender.map((gender) {
                                              return DropdownMenuItem(
                                                child: new Text(gender),
                                                value: gender,
                                              );
                                            }).toList(),
                                            validator: (value) {
                                              if (value == null)
                                                return "Please select your gender";
                                              return null;
                                            },
                                          ),
    

    Above code is in a page view,

    my variables

      List<String> _gender = ['Male', 'Female'];
      String _selectedGender;
    

    My entire Form code : just reduced to one field its very long

    
    class SignUp extends StatefulWidget {
      @override
      _SignUpState createState() => _SignUpState();
    }
    
    class _SignUpState extends State<SignUp> {
      final List<GlobalKey<FormState>> _page = [
        GlobalKey<FormState>(),
        GlobalKey<FormState>(),
        GlobalKey<FormState>(),
      ];
    
      final _key = GlobalKey<ScaffoldState>();
      
     
      List<String> _gender = ['Male', 'Female'];
      String _selectedGender;
    
        void changePage() {
        if (currentPageValue < 3) {
          if (_page[currentPageValue].currentState.validate()) {
            setState(() {
              currentPageValue += 1;
            });
          }
        }
      }
      
    
    
      @override
      Widget build(BuildContext context) {
        var deviceSize = MediaQuery.of(context).size;
        var deviceWidth = deviceSize.width;
    
        return Scaffold(
          key: _key,
          backgroundColor: _backgroundColor,
          appBar: AppBar(
            backgroundColor: _backgroundColor,
            leading: IconButton(
                icon: Icon(
                  currentPageValue == 0 ? Icons.close : Icons.keyboard_backspace,
                  size: 20.0,
                  color: _headerColor,
                ),
                onPressed: currentPageValue == 0
                    ? () => Navigator.pop(context)
                    : () => back()),
            centerTitle: true,
            elevation: 0.0,
          ),
          body: Form(
            key: _page[0],
            child: Container(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                 
                    Container(
                      width: deviceWidth * 0.9,
                      height: dropDownHeight,
                      child: ButtonTheme(
                        child: DropdownButtonFormField(
                          isExpanded: true,
                          hint: Text('Gender'),
                          value: _selectedGender,
                          onChanged: (newValue) {
                            setState(() {
                              _selectedGender = newValue;
                            });
                          },
                          items: _gender.map((gender) {
                            return DropdownMenuItem(
                              child: new Text(gender),
                              value: gender,
                            );
                          }).toList(),
                          validator: (value) {
                            if (value == null) return "Please select your gender";
                            return null;
                          },
                        ),
                      ),
                    ),
                   RaisedButton(
                                        color: buttonColor,
                                        shape: RoundedRectangleBorder(
                                          borderRadius:
                                              BorderRadius.circular(10.0),
                                        ),
                                        child: Text(
                                          'Next',
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontWeight: FontWeight.w400,
                                          ),
                                        ),
                                        onPressed: () => changePage(),
                                      ),
                ],
              ),
            ),
          ),
        );
    
    • joaomarcos96
      joaomarcos96 over 3 years
      Which Flutter version you're using?
    • Michael
      Michael over 3 years
      Flutter 1.20.2
    • joaomarcos96
      joaomarcos96 over 3 years
      Post the Form code and the code that is validating that Form please
    • joaomarcos96
      joaomarcos96 over 3 years
      I've created a DartPad with your current code, and it's working: dartpad.dev/cfef9877ad1370f348d28c7fb918be33
    • Michael
      Michael over 3 years
      thanks for the help seen your sample works fine there must be a bug am introducing in my code
    • Michael
      Michael over 3 years
      Have added the form code for you at the end of the original post
    • joaomarcos96
      joaomarcos96 over 3 years
      Pass the page number to changePage method: void changePage(int pageNumber) , and validate this way: _page[pageNumber].currentState.validate()
    • joaomarcos96
      joaomarcos96 over 3 years
      Anyway, I wouldn't have 3 global form states like you're doing. You'd better create 3 different Forms, and validate them separately. To do so, you can just wrap the fields into their respective Form and be sure not to mix the forms nor have them one inside the other.