Home > Mobile >  How to validate dropdown field in flutter
How to validate dropdown field in flutter

Time:10-19

I'm very new to flutter and have been trying to follow online tutorials on how to validate my fields but none of them seem to work. I'm trying to validate my dropdown field to be required. Any help would be greatly appreciated.

final _dropDownKey = GlobalKey<FormBuilderFieldState>();

Widget _buildKeystageField() {
return FutureBuilder<List<dynamic>>(
    future: placementService.fetchKeystages(),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return FormBuilderDropdown<String>(
          key: _dropDownKey,
          autovalidateMode: AutovalidateMode.onUserInteraction,
          name: 'keystage',
          allowClear: true,
          validator: (String? value) {
            if (value != null && value.isEmpty) {
              return "Keystage cannot be empty";
            }
            return null;
          },
          hint: const Text('Please Select Keystage'),
          icon: const Icon(Icons.arrow_drop_down),
          decoration: InputDecoration(
            labelText: 'Keystage',
            suffix: _keystageHasError
                ? const Icon(Icons.error)
                : const Icon(Icons.check),
          ),
          items: snapshot.data!.map<DropdownMenuItem<String>>((item) {
            return DropdownMenuItem<String>(
              alignment: AlignmentDirectional.center,
              value: item['id'].toString(),
              child: Text(item['age_group']),
            );
          }).toList(),
          onChanged: (value) {
            setState(() {
              _keystageValue = value!;
              print(value);
            });
          },
        );
      } else {
        const Text('Loading...');
        const CircularProgressIndicator();
      }
      return Center(
          child: Column(
        children: const [
          Text('Loading...'),
          CircularProgressIndicator(),
        ],
      ));
    });

}

Working code. Adapted from the answer provided. Changed how I create the dropdown menu and it all seems to work now. The code :

final _dropDownKey = GlobalKey<FormBuilderFieldState>();

Widget _buildKeystageField() {
return FutureBuilder<List<dynamic>>(
    future: placementService.fetchKeystages(),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return DropdownButtonFormField(
          key: _dropDownKey,
          autovalidateMode: AutovalidateMode.always,
          hint: const Text('Please Select Keystage'),
          icon: const Icon(Icons.arrow_drop_down),
          decoration: InputDecoration(
            labelText: 'Keystage',
            suffix: _keystageHasError
                ? const Icon(Icons.error)
                : const Icon(Icons.check),
          ),
          items: snapshot.data!.map<DropdownMenuItem<String>>((item) {
            return DropdownMenuItem<String>(
              alignment: AlignmentDirectional.center,
              value: item['id'].toString(),
              child: Text(item['age_group']),
            );
          }).toList(),
          onChanged: (String? value) {
            setState(() {
              _keystageValue = value!;
              print(value);
            });
          },
          validator: (String? value) {
            return value == null ? "Choose item from list" : null;
          },
        );
      } else {
        const Text('Loading...');
        const CircularProgressIndicator();
      }
      return Center(
          child: Column(
        children: const [
          Text('Loading...'),
          CircularProgressIndicator(),
        ],
      ));
    });

}

CodePudding user response:

It is a minimal code for validating the drop-down list. (Without using any 3rd party packages.)

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  List<String> list = <String>[
    "heads",
    "tails",
  ];

  String? dropDownValue;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Form(
          key: _formKey,
          child: Column(
            children: <Widget>[
              DropdownButtonFormField<String>(
                autovalidateMode: AutovalidateMode.always,
                value: dropDownValue,
                items: list.map(
                  (String label) {
                    return DropdownMenuItem<String>(
                      value: label,
                      child: Text(
                        label,
                      ),
                    );
                  },
                ).toList(),
                hint: const Text("Choose"),
                onChanged: (String? value) {
                  dropDownValue = value;
                  setState(() {});
                },
                validator: (String? value) {
                  return value == null ? "Choose item from list" : null;
                },
              ),
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState?.validate() ?? false) {
                    // validation passed
                  } else {
                    // validation failed
                  }
                },
                child: const Text("Submit"),
              )
            ],
          ),
        ),
      ),
    );
  }
}
  • Related