Flutter dropdown, select is disabled on validation error
1,289
Looking at your code, I strongly recommend you create 3 different Form
s 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),
),
],
),
),
],
),
);
}
}
Author by
Michael
Updated on December 23, 2022Comments
-
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 over 3 yearsWhich Flutter version you're using?
-
Michael over 3 yearsFlutter 1.20.2
-
joaomarcos96 over 3 yearsPost the Form code and the code that is validating that Form please
-
joaomarcos96 over 3 yearsI've created a DartPad with your current code, and it's working: dartpad.dev/cfef9877ad1370f348d28c7fb918be33
-
Michael over 3 yearsthanks for the help seen your sample works fine there must be a bug am introducing in my code
-
Michael over 3 yearsHave added the form code for you at the end of the original post
-
joaomarcos96 over 3 yearsPass the page number to
changePage
method:void changePage(int pageNumber)
, and validate this way:_page[pageNumber].currentState.validate()
-
joaomarcos96 over 3 yearsAnyway, I wouldn't have 3 global form states like you're doing. You'd better create 3 different
Form
s, and validate them separately. To do so, you can just wrap the fields into their respectiveForm
and be sure not to mix the forms nor have them one inside the other.
-