Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validator pushed TextFormField above

Tags:

flutter

I tried creating an email textfield with validator using TextFormField. Since the textfield height is too much for my liking, I wrap the TextFormField with Container and set the height to 50. Now the problem is whenever I submitted intended wrong value, the validator will popped out and pushed the textfield, leaving the height much smaller than what I set in Container.

Before submitting:

Before submitting

After submitting:

enter image description here

Here is my codes:

Widget _emailForm() {
    return Form(
      key: _emailFormKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Text("Enter Your Email", style: TextStyle(fontSize: 13.0, fontWeight: FontWeight.bold),),
          Padding(padding: EdgeInsets.symmetric(vertical: 4.0),),
          Container(
            height: 50,
            child: TextFormField(
              focusNode: _emailFocusNode,
              style: TextStyle(fontSize: 11.0, fontWeight: FontWeight.w600),
              keyboardType: TextInputType.emailAddress,
              controller: _emailTextController,
              decoration: InputDecoration(
                isDense: true,
                focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(0.0),),
                ),
                suffixIcon: IconButton(
                  alignment: Alignment.centerRight,
                  iconSize: 16.0,
                  icon: Icon(Icons.clear),
                  onPressed: () {
                    if(_emailTextController != null) {
                        _emailTextController.clear();
                        FocusScope.of(context).requestFocus(_emailFocusNode);
                    }
                  },
                ),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(
                    Radius.circular(0.0),
                  ),
                  borderSide: BorderSide(
                    color: Colors.black,
                    width: 1.0
                  )
                ),
                errorStyle: _errorTextStyle,
              ),
              validator: (val) {
                Pattern pattern = r'@';
                RegExp regex = RegExp(pattern);
                if(val.isEmpty) return "* Email address can't be empty";
                else if(!regex.hasMatch(val)) return "* Invalid email address";
                else {
                  return null;
                }
              },
            ),
          ),
          Padding(padding: EdgeInsets.symmetric(vertical: 6.0),),
          FlatButton(
            child: Text("Join".toUpperCase(), style: TextStyle(color: Colors.white, fontSize: 11),),
            onPressed: (){
              if(_emailFormKey.currentState.validate()) {
                _joinWaitingList();
              }
            },
            color: _themeColor,
          ),
        ],
      ),
    );
  }

This widget is part of ListView in my build method if that information is helping. Is there any way to solve this problem? Thanks!

like image 516
Zerocchi Avatar asked May 09 '19 08:05

Zerocchi


2 Answers

The problem is that TextField and TextFormField size themselves to include all of their content and decoration. If you add some error text onto the bottom of the TextFormField, then it will include that in its height. When it tries to size itself to fit into your Container, it doesn't have as much space for the input.

You could work around this by specifying the height of your Container in both the valid and invalid states. You'll have to fiddle with the exact invalid height, but it might look something like this:

Container(
  height: _isInvalid ? 100 : 50,
  TextFormField(),
),

Another option is to add counterText: ' ' to your InputDecoration and then size the Container to the size that you want. This will give you extra space to fit the error text without needing to change the height of the TextFormField.

Container(
  height: 100,
  TextFormField(
    decoration: InputDecoration(
      counterText: ' ',
    ),
  ),
),

The cleanest solution, if it's possible for you, may be to not use a Container at all. If you can create the input you want just by using InputDecoration and things like contentPadding etc., it will likely make this a lot cleaner.

like image 145
Justin McCandless Avatar answered Sep 29 '22 12:09

Justin McCandless


hey i think that its works if u use onchanged instead of validator :

 onChanged: (val) {
                Pattern pattern = r'@';
                RegExp regex = RegExp(pattern);
                if(val.isEmpty) return "* Email address can't be empty";
                else if(!regex.hasMatch(val)) return "* Invalid email address";
                else {
                  return null;
                }
              },
like image 21
GirlWhoCode Avatar answered Sep 29 '22 13:09

GirlWhoCode