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

Time:12-13

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

CodePudding user response:

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

CodePudding user response:

It seems you are also using _formChecked to avoid the error messages right at the time of app launch.

The problem is that at app launch since _formChecked is false, the autovalidateMode is set to disabled and when you encounter an invalid entry, _formChecked remains false, thereby not resetting the values of autovalidateMode until all fields are validated.

To fix this:

  • Firstly, you need to keep autovalidateMode set to always for all fields.
  • Secondly, setState should be called each time the save button is pressed so that validation results are reset.
  • Thirdly, a new bool variable needs to be introduced that would contain the result of validation. Its value would be used to decide whether the data needs to be added or not.
  • Last but not the least, _formChecked will now be used solely for the purpose of checking whether the form has been checked at least for the first time or not. Its value will be updated to true on the first form check. In order to avoid the error messages at the app launch, all code inside the validator function needs to be executed only if _formChecked is true.

Here is the revised code:

@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: AutovalidateMode.always,
            validator: (value) {
              if (_formChecked) {
                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: AutovalidateMode.always,
            validator: (value) {
              if (_formChecked) {
                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: AutovalidateMode.always,
            validator: (value) {
              if (_formChecked) {
                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: AutovalidateMode.always,
            validator: (value) {
              if (_formChecked) {
                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: AutovalidateMode.always,
            validator: (value) {
              if (_formChecked) {
                if (value == null || cityNameController?.text.trim() == "") {
                  return "This field cannot be empty";
                }
                return null;
              }
            },
            decoration: const InputDecoration(labelText: "City"),
          ),
        ),
      ])),
      bottomNavigationBar: MaterialButton(
        onPressed: () {
          if (_formChecked == false) _formChecked = true;
          bool isValidated;
          if (_fullNameKey.currentState!.validate() &&
              _phoneNumberKey.currentState!.validate() &&
              _cityNameKey.currentState!.validate() &&
              _houseNumberKey.currentState!.validate() &&
              _roadNameKey.currentState!.validate()) {
            print("Helllllllllllllllllllloo");
            isValidated = true;
          } else {
            isValidated = false;
          }
          setState(() {
            if (isValidated) {
              // Here create the model and add
            }
          });
        },
        child: Text("Save Address"),
      ),
    );
  }

Hope it helps!

  • Related