How to change the position of validation error in flutter forms?

Viewed 7583

I have a TextFormField to collect user authentication input, and it's pretty fine.

But when it shows the validation message, this happens:

How can I change the position of the error message to this do not happen anymore? I just want a way do easy fix this and the field still pretty. Here is the code.

Form(
              key: _formKey,
              child: Container(
                width: double.infinity,
                height: 40,
                decoration: BoxDecoration(
                  color: Colors.white,
                  boxShadow: [
                    BoxShadow(
                      blurRadius: 1.1,
                      color: Colors.black45,
                      spreadRadius: 0.5,
                      offset: Offset(
                        1.5,
                        2,
                      ),
                    ),
                  ],
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 15),
                  child: SizedBox(
                    height: 40,
                    child: TextFormField(
                      style: TextStyle(color: Colors.black),
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        disabledBorder: InputBorder.none,
                        enabledBorder: InputBorder.none,
                        errorBorder: InputBorder.none,
                        focusedBorder: InputBorder.none,
                        focusedErrorBorder: InputBorder.none,
                        hintText: 'Full name',
                        hintStyle: TextStyle(color: Colors.grey[600]),
                        icon: Icon(Icons.account_circle, color: Colors.black),
                      ),
                      onSaved: (string) => _formData['name'] = string,
                      validator: (string) {
                        if (string.isEmpty) {
                          return 'Field can\'t be empty';
                        }
                        return null;
                      },
                    ),
                  ),
                ),
              ),
            )
4 Answers

You can show error message below text field so that you UI won't disturb. You need to put TextFormField and Container with box decoration in a stack. Now when validator will show error message then container with not grow and gives an impression that error message is showing below TextFormField.

                 Stack(children: [
                    Container(
                        height: 48,
                        decoration: BoxDecoration(
                          color: Colors.grey.shade200,
                          borderRadius: BorderRadius.circular(30),
                        )),
                     TextFormField(
                      validator: (val) =>
                          val.length < 1 ? 'Name Required' : null,
                      onSaved: (val) => _username = val,
                      obscureText: false,
                      keyboardType: TextInputType.name,
                      controller: _controllerUsername,
                      autocorrect: false,
                      decoration: InputDecoration(
                        hintText: 'Name',
                        border: InputBorder.none,
                        focusedBorder: OutlineInputBorder(
                            borderRadius:
                                BorderRadius.all(Radius.circular(30.0)),
                            borderSide: BorderSide(color: Colors.blue)),
                        contentPadding: EdgeInsets.symmetric(
                            vertical: 15, horizontal: 20),
                      ),
                    ),]

Just set the helper text like that:

TextFormField(
    decoration: const InputDecoration(
        helperText: ' ',
    ),
    validator: myValidator,
),

You can check the below code.

Widget _buildEmailTextField()) {
    return Container(
        height: 35,
        child: Theme(
          data: new ThemeData(
            primaryColor: Color(0xFF262C48),
            primaryColorDark: Color(0xFF262C48),
          ),
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                SizedBox(
                  height: 20,
                ),
                Container(
                  child: TextFormField(
                    keyboardType: TextInputType.emailAddress,
                    validator: (val) {
                      bool emailValid = RegExp(
                              r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
                          .hasMatch(val);
                      if (!emailValid) {
                        return 'Invalid Email Address';
                      } else {
                        return null;
                      }
                    },
                    controller: emailController,
                    readOnly: isLoading ? true : false,
                    decoration: InputDecoration(
                      fillColor: Color(0xFFd9d8d8),
                      filled: true,

                      border: new OutlineInputBorder(
                          borderRadius: const BorderRadius.all(
                            const Radius.circular(7.0),
                          ),
                          borderSide:
                              BorderSide(color: Color(0xFF262C48), width: 2.0)),
                      contentPadding: new EdgeInsets.symmetric(
                          vertical: 25.0, horizontal: 10.0),
                      // prefixIcon: Icon(
                      //   Icons.email,
                      //   color: Color(0xFF008577),
                      // ),
                      hintText: 'Email',
                    ),
                  ),
                ),
                
                RaisedButton(
                  onPressed: () {
                    // Validate returns true if the form is valid, otherwise false.
                    if (_formKey.currentState.validate()) {
                      // If the form is valid, display a snackbar. In the real world,
                      // you'd often call a server or save the information in a database.

                      Scaffold.of(context).showSnackBar(
                          SnackBar(content: Text('Processing Data')));
                    }
                  },
                  child: Text('Submit'),
                )
              ],
            ),
          ),
        ),
      );
  }

Just put a container as a parent of textfield can solve the error.

we create value like this

int testForPhoneNumber = 0;

and change this value to two cases

the first case if phone number (my exmaple) is validate I set the value to 0

the second case if phone number is not validate I set the value to 1

so I do this in code ==> (testForPhoneNumber == 0)? .... : ....,

the point is represent the same thing but I change this in

InputDecoration in first case : contentPadding: EdgeInsets.fromLTRB(10, 10, 10, 0),

in second case : contentPadding: EdgeInsets.fromLTRB(10, 50, 10, 0),

the points represent in the picture below

Note I change the top of text.

this is the code

https://drive.google.com/file/d/1v-THl1GBDl1oaVmNVao9ghRJaI2MjnMj/view?usp=sharing

Related