Purushotam Kumar
Purushotam Kumar

Reputation: 1092

TextFormField displaying error message even after the values are inserted (using Form Flutter)

I am experimenting with flutter and I am stucked with a silly problem. I have defined two TextInputField in a screen, and I am validating using Form. Everything is working fine, my only problem, error is not going away even after values which is inserted are fine.

Below is the screenshot before entering the value. Error is showing at the start of the screen as well.

Screen at start

Below is the screen after entering the value. When i click on signup button, error is still showing.

Screen after entering the values

You can see, value is getting printed in logs when i click on Sign Up button.

Logs

Widget Class

class SignUpForm extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return SignUpState();
  }
}

State Class

class SignUpState extends State<SignUpForm> {
  final _fbKey = GlobalKey<FormState>();
  final UserDetails userDetails = UserDetails();
  bool _autoValidate = true;

  @override
  Widget build(BuildContext context) {
    return CustomScreenBg(
      AppString.additional_information,
      CustomCard(_getSignUpForm(context)),
    );
  }

  _getSignUpForm(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(12),
      child: Form(
        key: _fbKey,
        autovalidate: _autoValidate,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                RichText(
                  text: TextSpan(
                    text: AppString.welcome_to,
                    style: TextStyle(
                      color: AppColor.BLACK.toColor,
                      fontSize: 18,
                    ),
                    children: <TextSpan>[
                      TextSpan(
                        text: '${AppString.app_name}',
                        style: TextStyle(
                          fontSize: 24,
                          color: AppColor.PRIMARY_COLOR.toColor,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
            SizedBox(height: 4),
            Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                SubTitleText(AppString.lets_get_started),
              ],
            ),
            SizedBox(height: 16),
            Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                TextFormField(
                  decoration: InputDecoration(
                    labelText: AppString.enter_name,
                    errorText: AppString.error_name,
                  ),
                  keyboardType: TextInputType.text,
                  validator: (value) {
                    if (value.length < 4) {
                      return AppString.error_name;
                    }
                    return null;
                  },
                  onSaved: (name) {
                    userDetails.name = name;
                  },
                ),
                SizedBox(height: 16),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: AppString.enter_email,
                    errorText: AppString.error_email,
                  ),
                  keyboardType: TextInputType.text,
                  validator: (value) {
                    if (value.length < 5 || !value.contains('@')) {
                      return AppString.error_email;
                    }
                    return null;
                  },
                  onSaved: (email) {
                    userDetails.email = email;
                  },
                ),
              ],
            ),
            SizedBox(height: 24),
            Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                CustomButton(
                  AppString.sign_up,
                  () {
                    _onSubmit();
                  },
                  textColor: AppColor.WHITE.toColor,
                  bgColor: AppColor.PRIMARY_COLOR.toColor,
                ),
              ],
            ),
            SizedBox(height: 12)
          ],
        ),
      ),
    );
  }

  _onSubmit() {
    if (_fbKey.currentState.validate()) {
      _fbKey.currentState.save();
      print(userDetails.name);
      print(userDetails.email);
    } else {
      setState(() {
        _autoValidate = true;
      });
    }
  }
}

This method is getting called when clicking on Sign Up Button.

_onSubmit() {
    if (_fbKey.currentState.validate()) {
      _fbKey.currentState.save();
      print(userDetails.name);
      print(userDetails.email);
    } else {
      setState(() {
        _autoValidate = true;
      });
    }
  }

Can someone help me in figuring it out, what i am doing wrong?

Upvotes: 6

Views: 17985

Answers (4)

Hijbullah Al Mahmud
Hijbullah Al Mahmud

Reputation: 1

Just need to add this line to your Form widget.

 autovalidateMode: AutovalidateMode.onUserInteraction,

This autovalidateMode: AutovalidateMode.onUserInteraction, will validate automatically.

Form(
   key: _formKey,              
   autovalidateMode: AutovalidateMode.onUserInteraction,
   child: TextField(),
 )

Upvotes: 0

Ethirallan
Ethirallan

Reputation: 941

TextFormFiled has a new property since v1.19, called autovalidateMode. It provides multiple modes, but I think thast AutovalidateMode.onUserInteraction works best. It only autovalidate the Form after each user interaction.

Upvotes: 4

Midhun MP
Midhun MP

Reputation: 107121

You don't have to set the errorText property, when validation fails it will show the message returned by the validator callback. So for fixing the issue, all you want is to remove errorText from your TextFormField.

Upvotes: 2

Mohammad Assad Arshad
Mohammad Assad Arshad

Reputation: 1784

In my experience it is better to control the autoValidate property yourself. So following an example from here

First set class Boolean variable :

bool _autovalidate = false;

Then pass it to your form:

Form(
key: _fbKey,
autovalidate: _autovalidate,
... 
)

Then in your validator:

validator: (value) {
                if (value.length < 5 || !value.contains('@')) {

                  return AppString.error_email;
                  setState(() => _autoValidate = true);
                }
                return null;
              }

Upvotes: 4

Related Questions