Search code examples
validationflutterdartdropdown

Flutter dropdown, select is disabled on validation error


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(),
                                  ),
            ],
          ),
        ),
      ),
    );

Solution

  • 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),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      }
    }