Search code examples
flutterformsvalidationtextformfield

autoValidate isn't working simultaneously instead it is checking one by one


I am trying to take the details of the address , the problem i am facing is after i click the button where _formchecked is set to true the autovalidate is working only for one TextFormField at a time , Why the autovalidate not working simultaneously on all the textformfield

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

  @override
  State<AddAddress> createState() => _AddAddressState();
}

class _AddAddressState extends State<AddAddress> {
  final _fullNameKey = GlobalKey<FormState>();
  final _phoneNumberKey = GlobalKey<FormState>();
  final _houseNumberKey = GlobalKey<FormState>();
  final _roadNameKey = GlobalKey<FormState>();
  final _cityNameKey = GlobalKey<FormState>();

  TextEditingController? fullNameController;
  TextEditingController? phoneNumberController;
  TextEditingController? houseNumberController;
  TextEditingController? roadNameController;
  TextEditingController? cityNameController;
  bool _formChecked = false;
  bool checkedValue = false;
  final List<bool> _isSelected = [true, false];
  @override
  void initState() {
    fullNameController = TextEditingController();
    phoneNumberController = TextEditingController();
    houseNumberController = TextEditingController();
    roadNameController = TextEditingController();
    cityNameController = TextEditingController();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: "Add New Address".appBarText(),
          leading: const Icon(Icons.navigate_before),
        ),
        body: SingleChildScrollView(
            child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Form(
              key: _fullNameKey,
              child: TextFormField(
                controller: fullNameController,
                autovalidateMode: _formChecked
                    ? AutovalidateMode.always
                    : AutovalidateMode.disabled,
                validator: (value) {
                  if (value == null || fullNameController?.text.trim() == "") {
                    return "Name cannot be empty";
                  }
                  if (value.length < 3) {
                    return "Username must be greater than 3 characters";
                  }
                  return null;
                },
                decoration: InputDecoration(
                    labelText: "Full Name",
                    labelStyle: textStyleMediumRegular()),
              ),
            ),
            Form(
              key: _phoneNumberKey,
              child: TextFormField(
                keyboardType: TextInputType.phone,
                controller: phoneNumberController,
                autovalidateMode: _formChecked
                    ? AutovalidateMode.always
                    : AutovalidateMode.disabled,
                validator: (value) {
                  if (value == null ||
                      phoneNumberController?.text.trim() == "") {
                    return "Phone Number cannot be empty";
                  }
                  if (value.length < 10 || value.length > 13) {
                    return "Invalid Phone Number";
                  }
                  return null;
                },
                decoration: const InputDecoration(labelText: "Phone Number"),
              ),
            ),
            Form(
              key: _houseNumberKey,
              child: TextFormField(
                controller: houseNumberController,
                autovalidateMode: _formChecked
                    ? AutovalidateMode.always
                    : AutovalidateMode.disabled,
                validator: (value) {
                  if (value == null ||
                      houseNumberController?.text.trim() == "") {
                    return "This field cannot be empty";
                  }
                  return null;
                },
                decoration: const InputDecoration(
                    labelText: "House Name, Building Number"),
              ),
            ),
            Form(
              key: _roadNameKey,
              child: TextFormField(
                controller: roadNameController,
                autovalidateMode: _formChecked
                    ? AutovalidateMode.always
                    : AutovalidateMode.disabled,
                validator: (value) {
                  if (value == null || roadNameController?.text.trim() == "") {
                    return "This field cannot be empty";
                  }
                  return null;
                },
                decoration:
                    const InputDecoration(labelText: "Road Name, Area, Colony"),
              ),
            ),
            Form(
              key: _cityNameKey,
              child: TextFormField(
                controller: cityNameController,
                autovalidateMode: _formChecked
                    ? AutovalidateMode.always
                    : AutovalidateMode.disabled,
                validator: (value) {
                  if (value == null || cityNameController?.text.trim() == "") {
                    return "This field cannot be empty";
                  }
                  return null;
                },
                decoration: const InputDecoration(labelText: "City"),
              ),
            ),
        )),
        bottomNavigationBar: FilledButton(
          onPressed: () {
            if (_fullNameKey.currentState!.validate() &&
                _phoneNumberKey.currentState!.validate() &&
                _cityNameKey.currentState!.validate() &&
                _houseNumberKey.currentState!.validate() &&
                _roadNameKey.currentState!.validate()) {
              print("Helllllllllllllllllllloo");
              // Here create the model and add
              setState(() {
                _formChecked = true;
              });
            }
          },
          child: Text("Save Address"),
        );
  }
}

Solution

  • Move setState out of if branch. It is only called when all forms are valid.

    onPressed: () {
      if (_fullNameKey.currentState!.validate() &&
          _phoneNumberKey.currentState!.validate() &&
          _cityNameKey.currentState!.validate() &&
          _houseNumberKey.currentState!.validate() &&
          _roadNameKey.currentState!.validate()) {
        print("Helllllllllllllllllllloo");
        // Here create the model and add
      }
      setState(() {
        _formChecked = true;
      });
    },