Errortext property of InputDecorator causes padding

I have two text inputs in the same row (refer to images), when the errortext property of the inputdecorator is shown it causes the text field to get padding somehow and pop out of place, even the label moves its position. I have read a few posts on this issue and have tried their recommendations of giving the container a fixed size, putting it into a sizedBox etc but none of the solutions worked can someone give me a suggestion.

errorafter

here’s my code for the row that the text fields are in

Container(
                        margin: EdgeInsets.fromLTRB(15, 0, 15, 0),
                        child: Row(
                          children: <Widget>[
                            Expanded(
                              flex: 1,
                              child: FormField<String>(
                                builder: (FormFieldState<String> state) {
                                  return InputDecorator(
                                    decoration: InputDecoration(
                                      errorStyle: TextStyle(
                                        color: Colors.redAccent,
                                        fontSize: 16.0,
                                      ),
                                      labelText: "Year :",
                                      labelStyle: TextStyle(
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold,
                                        fontSize: 18,
                                      ),
                                      fillColor: Colors.white,
                                      filled: true,
                                      contentPadding: EdgeInsets.all(15),
                                      enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.grey,
                                          style: BorderStyle.solid,
                                          width: 1,
                                        ),
                                      ),
                                      errorText: (!showYearError) ? null : _enteredYearValidation(), 
                                    ), 
                                    child: TextFormField(
                                      autocorrect: false,
                                      controller: yearTextController,  
                                      keyboardType: TextInputType.number,
                                      decoration: InputDecoration.collapsed(
                                        hintText: " ",
                                      ),
                                    ),
                                );
                              },
                            )),
                            SizedBox(
                              width: 12,
                            ),
                            Expanded(
                              flex: 1,
                              child: FormField<String>(
                                builder: (FormFieldState<String> state) {
                                  return InputDecorator(
                                    decoration: InputDecoration(  
                                      errorStyle: TextStyle(
                                        color: Colors.redAccent,
                                        fontSize: 16.0
                                      ),
                                      labelText: "Mileage  :",
                                      labelStyle: TextStyle(
                                        color: Colors.black,
                                        fontWeight: FontWeight.bold,
                                        fontSize: 18,
                                      ),
                                      fillColor: Colors.white,
                                      filled: true,
                                      hintText: 'Please select expense',   
                                      contentPadding: EdgeInsets.all(15),
                                      enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.grey,
                                          style: BorderStyle.solid,
                                          width: 1,
                                        ),
                                      ),
                                    ),
                                    child: TextFormField(
                                      autocorrect: false,
                                      keyboardType: TextInputType.number,
                                      decoration: InputDecoration.collapsed(
                                        hintText: "",
                                      ),
                                    ),
                                );
                              },
                            )),
                          ],
                        ),
                      ),
1 Like

I will look into the issue but for future reference, when you are copy-pasting your code from editor, please enclose them with three backticks (front and trailing).

Hey @akashh The issue doesn’t lie with the TextFormField at all. The real issue lies with the Row.

By default the crossAxisAlignment property of row aligns its children to the center. Because which the mileage textfield shifts down. And also you should change enabledBorder property to Border if you want the rounded border to stay even during errors.

I modified your code in the following manner, notice the crossAxisAlignment.

Container(
  width: MediaQuery.of(context).size.width,
  margin: EdgeInsets.fromLTRB(15, 0, 15, 0),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Expanded(
        child: FormField(
          builder: (FormFieldState state) {
            return TextFormField(
              autovalidate: true,
              keyboardType: TextInputType.number,
              validator: (String value) {
                if (value.isEmpty) {
                  return 'Invalid Year';
                }
                return null;
              },
              decoration: InputDecoration(
                errorStyle: TextStyle(
                  color: Colors.redAccent,
                  fontSize: 16.0,
                ),
                labelText: "Year :",
                labelStyle: TextStyle(
                  color: Colors.black,
                  fontWeight: FontWeight.bold,
                  fontSize: 18,
                ),
                fillColor: Colors.white,
                filled: true,
                contentPadding: EdgeInsets.all(15),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(5),
                  borderSide: BorderSide(
                    color: Colors.grey,
                    style: BorderStyle.solid,
                    width: 1,
                  ),
                ),
              ),
            );
          },
        ),
      ),
      SizedBox(
        width: 12,
      ),
      Expanded(
        child: FormField(
          builder: (FormFieldState state) {
            return TextFormField(
                autocorrect: false,
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                  errorStyle: TextStyle(
                      color: Colors.redAccent, fontSize: 16.0),
                  labelText: "Mileage: ",
                  labelStyle: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 18,
                  ),
                  fillColor: Colors.white,
                  filled: true,
                  hintText: 'Please select expense',
                  contentPadding: EdgeInsets.all(15),
                  border: OutlineInputBorder(
                    borderSide: BorderSide(
                      color: Colors.grey,
                      style: BorderStyle.solid,
                      width: 1,
                    ),
                  ),
                ));
          },
        ),
      )
    ],
  ),
)
2 Likes

Hi Sakina,

Didn’t know about the back ticks I’m guessing that it should be applicable to any code.

Thanks for the code above it is even working wonderfully, I have a few questions though.

  1. The labels are now floating, is this because of the way you’ve declared it. I noticed it’s very different to mine, so am I doing it incorrectly?

  2. With the validator function in place is it even necessary to assign a text controller, why would I even need a text controller here?

  3. I now want to make the label not float so I inserted hasFloatingPlaceHolder and set it to false and now whenever the field has focus the label dissappears, how do I resolve this?

@akashh Glad I could be helpful.

  1. I personally feel it’s a more cleaner way to code, wouldn’t call your approach incorrect.
  2. No, you don’t need text controller in this particular case. TextController has many uses such as when you want to transform the text entered by the user, or if you want to use the text to compare with another textfield in real time.

for example, if there are two fields - password and confirmPassword, textController will be useful to check the confirmpassword matches the original.

validator: (String value) {
  if (_passwordTextController.text != value) {
    return 'Passwords do not match.';
  }
  return null;
}

Or if you want to perform any transformations like remove white spaces, etc. Note that this can be done by saving into another variable also.
3. Yes, that is the expected behaviour. I think what you are looking for is hintText, if you are looking for the following behaviour.
How do you want the label to behave when the field is focussed?

1 Like

Thanks for the detailed explanation.

I would like my label to float but when the text input is focused and it floats to the top it disappears. (refer to image). NB. this happens when hasFloatingPlaceholder set to false.

errorafter1

Yes, please don’t set it to false if you want it to float.

Yes I understand that but if I set it to false it disappears as per the image I’ve attached, how do I rectify this?

hasFloatingPlaceholder: false --------RELOAD after setting it false


hasFloatingPlaceholder: true